semantifold 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/bin/semantifold.js +6 -0
- package/build/bin/semantifold.d.ts +3 -0
- package/build/bin/semantifold.d.ts.map +1 -0
- package/build/bin/semantifold.js +5 -0
- package/build/index.d.ts +8 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +9 -1
- package/build/src/artifact-path.d.ts +16 -0
- package/build/src/artifact-path.d.ts.map +1 -1
- package/build/src/artifact-path.js +29 -3
- package/build/src/backends/c-check.d.ts +7 -0
- package/build/src/backends/c-check.d.ts.map +1 -0
- package/build/src/backends/c-check.js +65 -0
- package/build/src/backends/check-plan.d.ts +96 -0
- package/build/src/backends/check-plan.d.ts.map +1 -0
- package/build/src/backends/check-plan.js +135 -0
- package/build/src/backends/cpp-check.d.ts +7 -0
- package/build/src/backends/cpp-check.d.ts.map +1 -0
- package/build/src/backends/cpp-check.js +59 -0
- package/build/src/backends/csharp-check.d.ts +7 -0
- package/build/src/backends/csharp-check.d.ts.map +1 -0
- package/build/src/backends/csharp-check.js +125 -0
- package/build/src/backends/csharp.d.ts +1 -0
- package/build/src/backends/csharp.d.ts.map +1 -1
- package/build/src/backends/csharp.js +5 -4
- package/build/src/backends/dart-check.d.ts +7 -0
- package/build/src/backends/dart-check.d.ts.map +1 -0
- package/build/src/backends/dart-check.js +103 -0
- package/build/src/backends/dart.d.ts +2 -0
- package/build/src/backends/dart.d.ts.map +1 -1
- package/build/src/backends/dart.js +5 -5
- package/build/src/backends/go-check.d.ts +7 -0
- package/build/src/backends/go-check.d.ts.map +1 -0
- package/build/src/backends/go-check.js +77 -0
- package/build/src/backends/go.d.ts +1 -0
- package/build/src/backends/go.d.ts.map +1 -1
- package/build/src/backends/go.js +3 -3
- package/build/src/backends/java-check.d.ts +21 -0
- package/build/src/backends/java-check.d.ts.map +1 -0
- package/build/src/backends/java-check.js +73 -0
- package/build/src/backends/javascript-check.d.ts +7 -0
- package/build/src/backends/javascript-check.d.ts.map +1 -0
- package/build/src/backends/javascript-check.js +29 -0
- package/build/src/backends/kotlin-check.d.ts +7 -0
- package/build/src/backends/kotlin-check.d.ts.map +1 -0
- package/build/src/backends/kotlin-check.js +31 -0
- package/build/src/backends/php-check.d.ts +7 -0
- package/build/src/backends/php-check.d.ts.map +1 -0
- package/build/src/backends/php-check.js +21 -0
- package/build/src/backends/program.d.ts +7 -0
- package/build/src/backends/program.d.ts.map +1 -1
- package/build/src/backends/program.js +16 -1
- package/build/src/backends/python-check.d.ts +7 -0
- package/build/src/backends/python-check.d.ts.map +1 -0
- package/build/src/backends/python-check.js +28 -0
- package/build/src/backends/ruby-check.d.ts +7 -0
- package/build/src/backends/ruby-check.d.ts.map +1 -0
- package/build/src/backends/ruby-check.js +21 -0
- package/build/src/backends/rust-check.d.ts +7 -0
- package/build/src/backends/rust-check.d.ts.map +1 -0
- package/build/src/backends/rust-check.js +65 -0
- package/build/src/backends/swift-check.d.ts +7 -0
- package/build/src/backends/swift-check.d.ts.map +1 -0
- package/build/src/backends/swift-check.js +77 -0
- package/build/src/backends/typescript-check.d.ts +7 -0
- package/build/src/backends/typescript-check.d.ts.map +1 -0
- package/build/src/backends/typescript-check.js +33 -0
- package/build/src/backends/zig-check.d.ts +7 -0
- package/build/src/backends/zig-check.d.ts.map +1 -0
- package/build/src/backends/zig-check.js +70 -0
- package/build/src/diagnostic.d.ts +13 -1
- package/build/src/diagnostic.d.ts.map +1 -1
- package/build/src/diagnostic.js +14 -2
- package/build/src/frontends/program.d.ts +6 -0
- package/build/src/frontends/program.d.ts.map +1 -1
- package/build/src/frontends/program.js +9 -1
- package/build/src/language-registry.d.ts +54 -0
- package/build/src/language-registry.d.ts.map +1 -1
- package/build/src/language-registry.js +107 -5
- package/build/src/project-build.d.ts +172 -0
- package/build/src/project-build.d.ts.map +1 -0
- package/build/src/project-build.js +320 -0
- package/build/src/project-cli.d.ts +40 -0
- package/build/src/project-cli.d.ts.map +1 -0
- package/build/src/project-cli.js +145 -0
- package/build/src/project-manifest.d.ts +148 -0
- package/build/src/project-manifest.d.ts.map +1 -0
- package/build/src/project-manifest.js +432 -0
- package/build/src/project-reporter.d.ts +81 -0
- package/build/src/project-reporter.d.ts.map +1 -0
- package/build/src/project-reporter.js +293 -0
- package/build/src/project-snapshot.d.ts +129 -0
- package/build/src/project-snapshot.d.ts.map +1 -0
- package/build/src/project-snapshot.js +362 -0
- package/build/src/project-watch-reporter.d.ts +125 -0
- package/build/src/project-watch-reporter.d.ts.map +1 -0
- package/build/src/project-watch-reporter.js +280 -0
- package/build/src/project-watch.d.ts +133 -0
- package/build/src/project-watch.d.ts.map +1 -0
- package/build/src/project-watch.js +839 -0
- package/build/src/publication.d.ts +69 -5
- package/build/src/publication.d.ts.map +1 -1
- package/build/src/publication.js +246 -57
- package/build/src/semantic/types.d.ts +303 -2
- package/build/src/semantic/types.d.ts.map +1 -1
- package/build/src/semantic/types.js +79 -2
- package/build/src/subprocess.d.ts +8 -0
- package/build/src/subprocess.d.ts.map +1 -1
- package/build/src/subprocess.js +50 -9
- package/build/src/target-check.d.ts +52 -0
- package/build/src/target-check.d.ts.map +1 -0
- package/build/src/target-check.js +796 -0
- package/build/src/toolchains.d.ts.map +1 -1
- package/build/src/toolchains.js +3 -3
- package/docs/architecture.md +3 -1
- package/docs/c.md +4 -0
- package/docs/cpp.md +4 -0
- package/docs/dart.md +4 -0
- package/docs/generated-artifact-publication.md +11 -8
- package/docs/kotlin.md +2 -2
- package/docs/language-support.md +29 -3
- package/docs/project-build-cli.md +147 -0
- package/docs/project-watch.md +60 -0
- package/docs/rust.md +4 -0
- package/docs/swift.md +2 -0
- package/docs/testing.md +70 -3
- package/docs/watch-build-pipeline.md +39 -23
- package/docs/zig.md +2 -0
- package/examples/jsdoc-java-watch/expected-output.txt +3 -0
- package/examples/jsdoc-java-watch/semantifold.json +23 -0
- package/examples/jsdoc-java-watch/src/main.js +21 -0
- package/index.js +8 -0
- package/package.json +6 -1
- package/src/artifact-path.js +31 -2
- package/src/backends/c-check.js +80 -0
- package/src/backends/check-plan.js +147 -0
- package/src/backends/cpp-check.js +73 -0
- package/src/backends/csharp-check.js +139 -0
- package/src/backends/csharp.js +4 -3
- package/src/backends/dart-check.js +117 -0
- package/src/backends/dart.js +4 -4
- package/src/backends/go-check.js +89 -0
- package/src/backends/go.js +2 -2
- package/src/backends/java-check.js +77 -0
- package/src/backends/javascript-check.js +33 -0
- package/src/backends/kotlin-check.js +41 -0
- package/src/backends/php-check.js +23 -0
- package/src/backends/program.js +17 -0
- package/src/backends/python-check.js +30 -0
- package/src/backends/ruby-check.js +23 -0
- package/src/backends/rust-check.js +78 -0
- package/src/backends/swift-check.js +89 -0
- package/src/backends/typescript-check.js +37 -0
- package/src/backends/zig-check.js +81 -0
- package/src/diagnostic.js +9 -1
- package/src/frontends/program.js +9 -0
- package/src/language-registry.js +113 -4
- package/src/project-build.js +353 -0
- package/src/project-cli.js +155 -0
- package/src/project-manifest.js +479 -0
- package/src/project-reporter.js +320 -0
- package/src/project-snapshot.js +403 -0
- package/src/project-watch-reporter.js +303 -0
- package/src/project-watch.js +870 -0
- package/src/publication.js +275 -58
- package/src/semantic/types.js +87 -1
- package/src/subprocess.js +49 -8
- package/src/target-check.js +844 -0
- package/src/toolchains.js +3 -2
- package/tsconfig.json +1 -1
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { lstat, readFile, realpath } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { findPortableArtifactPathConflict, findPortableSourcePathConflict, isSafeArtifactPath, isSafeSourcePath } from "./artifact-path.js";
|
|
5
|
+
import { supportsProgramArtifactRole } from "./backends/program.js";
|
|
6
|
+
import { SemantifoldDiagnostic } from "./diagnostic.js";
|
|
7
|
+
import { supportsProgramSourceLanguage } from "./frontends/program.js";
|
|
8
|
+
import { languageRegistry } from "./language-registry.js";
|
|
9
|
+
const projectIdentityPattern = /^[a-z][a-z0-9-]*$/u;
|
|
10
|
+
const moduleIdentityPattern = /^[a-z][a-z0-9_]*(?:[.-][a-z][a-z0-9_]*)*$/u;
|
|
11
|
+
const sourceRoles = new Map([
|
|
12
|
+
["text", "textBackend"],
|
|
13
|
+
["binary", "binaryBackend"],
|
|
14
|
+
["application", "applicationBackend"]
|
|
15
|
+
]);
|
|
16
|
+
const manifestDefaultApplicationTargets = new Set(["android", "flutter"]);
|
|
17
|
+
const projectFields = ["id", "publicationRoot", "schema", "sources", "targets", "version"];
|
|
18
|
+
const sourceFields = ["entry", "id", "language", "path"];
|
|
19
|
+
const targetRequiredFields = ["id", "language", "role", "sourceProjection"];
|
|
20
|
+
const targetOptionalFields = ["buildProjection"];
|
|
21
|
+
/**
|
|
22
|
+
* One validated immutable Semantifold project request.
|
|
23
|
+
*/
|
|
24
|
+
export class SemantifoldProject {
|
|
25
|
+
/**
|
|
26
|
+
* Constructs a trusted normalized project value for the manifest loader.
|
|
27
|
+
* @param {NormalizedProject} value - Validated normalized fields.
|
|
28
|
+
*/
|
|
29
|
+
constructor(value) {
|
|
30
|
+
this.entryModule = value.entryModule;
|
|
31
|
+
this.id = value.id;
|
|
32
|
+
this.manifestPath = value.manifestPath;
|
|
33
|
+
this.manifestText = value.manifestText;
|
|
34
|
+
this.projectRoot = value.projectRoot;
|
|
35
|
+
this.publicationRoot = value.publicationRoot;
|
|
36
|
+
this.sources = Object.freeze(value.sources.map(source => Object.freeze({ ...source })));
|
|
37
|
+
this.targets = Object.freeze(value.targets.map(target => Object.freeze({ ...target })));
|
|
38
|
+
this.version = /** @type {const} */ (1);
|
|
39
|
+
Object.freeze(this);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Loads and validates the strict versioned project-manifest boundary.
|
|
44
|
+
*/
|
|
45
|
+
export class ProjectManifestLoader {
|
|
46
|
+
/**
|
|
47
|
+
* Loads one project manifest without reading source content.
|
|
48
|
+
* @param {string} [projectPath] - Manifest path, relative to the process working directory or absolute.
|
|
49
|
+
* @returns {Promise<SemantifoldProject>} Immutable normalized project.
|
|
50
|
+
*/
|
|
51
|
+
async load(projectPath = "./semantifold.json") {
|
|
52
|
+
if (typeof projectPath != "string" || projectPath.length == 0 || projectPath.includes("\0")) {
|
|
53
|
+
projectFailure("INVALID_PROJECT_MANIFEST", "project", "Project manifest path must be a non-empty path string.");
|
|
54
|
+
}
|
|
55
|
+
const manifestPath = path.resolve(projectPath);
|
|
56
|
+
const projectRoot = path.dirname(manifestPath);
|
|
57
|
+
await requireCanonicalProjectRoot(projectRoot);
|
|
58
|
+
await requireRegularFile(manifestPath, "semantifold.json", "PROJECT_MANIFEST_READ_FAILED");
|
|
59
|
+
let bytes;
|
|
60
|
+
try {
|
|
61
|
+
bytes = await readFile(manifestPath);
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
projectFailure("PROJECT_MANIFEST_READ_FAILED", "project", "Project manifest could not be read.", manifestLocation(), error);
|
|
65
|
+
}
|
|
66
|
+
let manifestText;
|
|
67
|
+
try {
|
|
68
|
+
manifestText = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
projectFailure("INVALID_PROJECT_MANIFEST", "project", "Project manifest must be valid UTF-8.", manifestLocation(), error);
|
|
72
|
+
}
|
|
73
|
+
let candidate;
|
|
74
|
+
try {
|
|
75
|
+
candidate = JSON.parse(manifestText);
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
projectFailure("INVALID_PROJECT_MANIFEST", "project", "Project manifest must contain valid JSON.", manifestLocation(), error);
|
|
79
|
+
}
|
|
80
|
+
return normalizeProject(candidate, { manifestPath, manifestText, projectRoot });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Validates and normalizes one parsed manifest.
|
|
85
|
+
* @param {unknown} candidate - Parsed JSON value.
|
|
86
|
+
* @param {{manifestPath: string, manifestText: string, projectRoot: string}} context - Canonical manifest context.
|
|
87
|
+
* @returns {Promise<SemantifoldProject>} Immutable project value.
|
|
88
|
+
*/
|
|
89
|
+
async function normalizeProject(candidate, context) {
|
|
90
|
+
if (!isPlainObject(candidate) || !hasExactKeys(candidate, projectFields)) {
|
|
91
|
+
projectFailure("INVALID_PROJECT_MANIFEST", "project", "Project manifest requires exactly the version-1 root fields.", manifestLocation());
|
|
92
|
+
}
|
|
93
|
+
const { id, publicationRoot, schema, sources, targets, version } = candidate;
|
|
94
|
+
if (schema != "SemantifoldProject" || version != 1) {
|
|
95
|
+
projectFailure("INVALID_PROJECT_MANIFEST", typeof id == "string" ? id : "project", "Project manifest requires schema 'SemantifoldProject' version 1.", manifestLocation());
|
|
96
|
+
}
|
|
97
|
+
if (typeof id != "string" || !projectIdentityPattern.test(id)) {
|
|
98
|
+
projectFailure("INVALID_PROJECT_MANIFEST", "project", "Project identity must be a stable lowercase ID.", manifestLocation());
|
|
99
|
+
}
|
|
100
|
+
if (!isSafeArtifactPath(publicationRoot)) {
|
|
101
|
+
projectFailure("INVALID_PROJECT_PATH", id, "Publication root must be one canonical project-relative path.", manifestLocation());
|
|
102
|
+
}
|
|
103
|
+
if (!isDenseArray(sources) || sources.length == 0) {
|
|
104
|
+
projectFailure("INVALID_PROJECT_MANIFEST", id, "Project sources must be a non-empty ordered array.", manifestLocation());
|
|
105
|
+
}
|
|
106
|
+
if (!isDenseArray(targets) || targets.length == 0) {
|
|
107
|
+
projectFailure("INVALID_PROJECT_MANIFEST", id, "Project targets must be a non-empty ordered array.", manifestLocation());
|
|
108
|
+
}
|
|
109
|
+
const normalizedPublicationRoot = path.join(context.projectRoot, publicationRoot);
|
|
110
|
+
const sourceIds = new Set();
|
|
111
|
+
const sourcePaths = [];
|
|
112
|
+
/** @type {NormalizedProjectSource[]} */
|
|
113
|
+
const normalizedSources = [];
|
|
114
|
+
let entryModule;
|
|
115
|
+
for (let index = 0; index < sources.length; index += 1) {
|
|
116
|
+
const source = sources[index];
|
|
117
|
+
if (!isPlainObject(source) || !hasExactKeys(source, sourceFields)) {
|
|
118
|
+
projectFailure("INVALID_PROJECT_MANIFEST", id, `Source ${index} requires exactly path, language, ID, and entry fields.`, manifestLocation());
|
|
119
|
+
}
|
|
120
|
+
if (typeof source.id != "string" || !moduleIdentityPattern.test(source.id) || sourceIds.has(source.id)) {
|
|
121
|
+
projectFailure("INVALID_PROJECT_MANIFEST", id, `Source ${index} has an invalid or duplicate module identity.`, manifestLocation());
|
|
122
|
+
}
|
|
123
|
+
if (!isSafeSourcePath(source.path)) {
|
|
124
|
+
projectFailure("INVALID_PROJECT_PATH", id, `Source '${source.id}' path must be canonical and project-relative.`, manifestLocation());
|
|
125
|
+
}
|
|
126
|
+
if (typeof source.language != "string") {
|
|
127
|
+
projectFailure("INVALID_PROJECT_MANIFEST", id, `Source '${source.id}' requires a registered source language.`, manifestLocation());
|
|
128
|
+
}
|
|
129
|
+
languageRegistry.resolve(source.language, "frontend", manifestLocation());
|
|
130
|
+
if (!supportsProgramSourceLanguage(source.language)) {
|
|
131
|
+
projectFailure("UNSUPPORTED_PROJECT_SOURCE", source.language, "Registered frontend does not participate in the explicit multi-file project profile.", manifestLocation());
|
|
132
|
+
}
|
|
133
|
+
if (typeof source.entry != "boolean") {
|
|
134
|
+
projectFailure("INVALID_PROJECT_MANIFEST", id, `Source '${source.id}' entry must be Boolean.`, manifestLocation());
|
|
135
|
+
}
|
|
136
|
+
if (source.entry) {
|
|
137
|
+
if (entryModule !== undefined) {
|
|
138
|
+
projectFailure("INVALID_PROJECT_MANIFEST", id, "Project sources must declare exactly one entry module.", manifestLocation());
|
|
139
|
+
}
|
|
140
|
+
entryModule = source.id;
|
|
141
|
+
}
|
|
142
|
+
const absolutePath = path.join(context.projectRoot, source.path);
|
|
143
|
+
if (portablePathsOverlap(source.path, publicationRoot)) {
|
|
144
|
+
projectFailure("PROJECT_SOURCE_PUBLICATION_OVERLAP", id, `Source '${source.id}' overlaps the publisher-owned publication root.`, manifestLocation());
|
|
145
|
+
}
|
|
146
|
+
sourceIds.add(source.id);
|
|
147
|
+
sourcePaths.push(source.path);
|
|
148
|
+
normalizedSources.push({
|
|
149
|
+
absolutePath,
|
|
150
|
+
entry: source.entry,
|
|
151
|
+
id: source.id,
|
|
152
|
+
language: /** @type {import("./semantic/types.js").SemanticLanguage} */ (source.language),
|
|
153
|
+
path: source.path
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
if (entryModule === undefined) {
|
|
157
|
+
projectFailure("INVALID_PROJECT_MANIFEST", id, "Project sources must declare exactly one entry module.", manifestLocation());
|
|
158
|
+
}
|
|
159
|
+
const sourceConflict = findPortableSourcePathConflict(sourcePaths);
|
|
160
|
+
if (sourceConflict) {
|
|
161
|
+
projectFailure("PROJECT_SOURCE_ALIAS", id, "Project source paths must be unique under portable comparison.", manifestLocation());
|
|
162
|
+
}
|
|
163
|
+
const sourceLanguages = new Set(normalizedSources.map(({ language }) => language));
|
|
164
|
+
if (sourceLanguages.size != 1) {
|
|
165
|
+
projectFailure("INVALID_PROJECT_MANIFEST", id, "A project must use one source-language compatibility profile.", manifestLocation());
|
|
166
|
+
}
|
|
167
|
+
await requireExistingProjectPaths(context.projectRoot, normalizedPublicationRoot, normalizedSources, id);
|
|
168
|
+
const targetIds = new Set();
|
|
169
|
+
/** @type {NormalizedProjectTarget[]} */
|
|
170
|
+
const normalizedTargets = [];
|
|
171
|
+
/** @type {string[]} */
|
|
172
|
+
const projections = [];
|
|
173
|
+
for (let index = 0; index < targets.length; index += 1) {
|
|
174
|
+
const target = targets[index];
|
|
175
|
+
if (!isPlainObject(target) || !hasRequiredAndOptionalKeys(target, targetRequiredFields, targetOptionalFields)) {
|
|
176
|
+
projectFailure("INVALID_PROJECT_MANIFEST", id, `Target ${index} contains missing or unknown fields.`, manifestLocation());
|
|
177
|
+
}
|
|
178
|
+
if (typeof target.id != "string" || !projectIdentityPattern.test(target.id) || targetIds.has(target.id)) {
|
|
179
|
+
projectFailure("INVALID_PROJECT_MANIFEST", id, `Target ${index} has an invalid or duplicate identity.`, manifestLocation());
|
|
180
|
+
}
|
|
181
|
+
if (typeof target.language != "string" || typeof target.role != "string" || !sourceRoles.has(target.role)) {
|
|
182
|
+
projectFailure("INVALID_PROJECT_MANIFEST", id, `Target '${target.id}' requires a registered target and explicit role.`, manifestLocation());
|
|
183
|
+
}
|
|
184
|
+
languageRegistry.resolve(target.language, /** @type {"textBackend" | "binaryBackend" | "applicationBackend"} */ (sourceRoles.get(target.role)), manifestLocation());
|
|
185
|
+
if (!supportsProgramArtifactRole(target.language, target.role)) {
|
|
186
|
+
projectFailure("UNSUPPORTED_PROJECT_TARGET", target.language, `Registered target does not support '${target.role}' generation for complete semantic programs.`, manifestLocation());
|
|
187
|
+
}
|
|
188
|
+
if (target.role == "application" && !manifestDefaultApplicationTargets.has(target.language)) {
|
|
189
|
+
projectFailure("UNSUPPORTED_PROJECT_TARGET", target.language, "Project manifest version 1 cannot express the target's required application configuration.", manifestLocation());
|
|
190
|
+
}
|
|
191
|
+
const buildProjection = target.buildProjection === undefined ? `targets/${target.id}/build` : target.buildProjection;
|
|
192
|
+
if (!isSafeArtifactPath(target.sourceProjection) || !isSafeArtifactPath(buildProjection)) {
|
|
193
|
+
projectFailure("INVALID_PROJECT_PATH", id, `Target '${target.id}' projections must be canonical generation-relative paths.`, manifestLocation());
|
|
194
|
+
}
|
|
195
|
+
targetIds.add(target.id);
|
|
196
|
+
projections.push(target.sourceProjection, buildProjection);
|
|
197
|
+
normalizedTargets.push({
|
|
198
|
+
buildProjection,
|
|
199
|
+
id: target.id,
|
|
200
|
+
language: /** @type {import("./semantic/types.js").BackendLanguage} */ (target.language),
|
|
201
|
+
role: /** @type {import("./semantic/types.js").PublicationTargetRole} */ (target.role),
|
|
202
|
+
sourceProjection: target.sourceProjection
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
if (findPortableArtifactPathConflict(projections)) {
|
|
206
|
+
projectFailure("PROJECT_PROJECTION_COLLISION", id, "Target source/build projections must be distinct and non-nested under portable comparison.", manifestLocation());
|
|
207
|
+
}
|
|
208
|
+
if (findPortableArtifactPathConflict([...projections, "manifest.json"])) {
|
|
209
|
+
projectFailure("INVALID_PROJECT_PATH", id, "Target source/build projections must not overlap the reserved generation manifest path.", manifestLocation());
|
|
210
|
+
}
|
|
211
|
+
return new SemantifoldProject({
|
|
212
|
+
entryModule,
|
|
213
|
+
id,
|
|
214
|
+
manifestPath: context.manifestPath,
|
|
215
|
+
manifestText: context.manifestText,
|
|
216
|
+
projectRoot: context.projectRoot,
|
|
217
|
+
publicationRoot: normalizedPublicationRoot,
|
|
218
|
+
sources: normalizedSources,
|
|
219
|
+
targets: normalizedTargets
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Requires a canonical real project root.
|
|
224
|
+
* @param {string} projectRoot - Absolute manifest directory.
|
|
225
|
+
* @returns {Promise<void>} Completion.
|
|
226
|
+
*/
|
|
227
|
+
async function requireCanonicalProjectRoot(projectRoot) {
|
|
228
|
+
try {
|
|
229
|
+
const exact = await realpath(projectRoot);
|
|
230
|
+
if (exact != projectRoot) {
|
|
231
|
+
projectFailure("PROJECT_SYMLINK_TRAVERSAL", "project", "Project root must not be reached through a symbolic link.", manifestLocation());
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
if (error instanceof SemantifoldDiagnostic)
|
|
236
|
+
throw error;
|
|
237
|
+
projectFailure("PROJECT_MANIFEST_READ_FAILED", "project", "Project root could not be resolved.", manifestLocation(), error);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Validates every source path and every existing publication-root component.
|
|
242
|
+
* @param {string} projectRoot - Canonical project root.
|
|
243
|
+
* @param {string} publicationRoot - Normalized publication root.
|
|
244
|
+
* @param {readonly NormalizedProjectSource[]} sources - Normalized sources.
|
|
245
|
+
* @param {string} projectId - Project identity.
|
|
246
|
+
* @returns {Promise<void>} Completion.
|
|
247
|
+
*/
|
|
248
|
+
async function requireExistingProjectPaths(projectRoot, publicationRoot, sources, projectId) {
|
|
249
|
+
await requireNoSymlinkComponents(projectRoot, publicationRoot, projectId, true);
|
|
250
|
+
const fileIdentities = new Set();
|
|
251
|
+
for (const source of sources) {
|
|
252
|
+
await requireNoSymlinkComponents(projectRoot, source.absolutePath, projectId, false);
|
|
253
|
+
const status = await requireRegularFile(source.absolutePath, source.path, "PROJECT_SOURCE_READ_FAILED", projectId);
|
|
254
|
+
const identity = `${String(status.dev)}:${String(status.ino)}`;
|
|
255
|
+
if (fileIdentities.has(identity)) {
|
|
256
|
+
projectFailure("PROJECT_SOURCE_ALIAS", projectId, "Project source paths must not alias the same file.", sourceLocation(source.path));
|
|
257
|
+
}
|
|
258
|
+
fileIdentities.add(identity);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Rejects symlinks beneath a canonical project root.
|
|
263
|
+
* @param {string} projectRoot - Canonical project root.
|
|
264
|
+
* @param {string} target - Absolute target.
|
|
265
|
+
* @param {string} projectId - Project identity.
|
|
266
|
+
* @param {boolean} allowMissing - Whether a missing suffix is permitted.
|
|
267
|
+
* @returns {Promise<void>} Completion.
|
|
268
|
+
*/
|
|
269
|
+
async function requireNoSymlinkComponents(projectRoot, target, projectId, allowMissing) {
|
|
270
|
+
const relative = path.relative(projectRoot, target);
|
|
271
|
+
let current = projectRoot;
|
|
272
|
+
for (const part of relative.split(path.sep).filter(Boolean)) {
|
|
273
|
+
current = path.join(current, part);
|
|
274
|
+
try {
|
|
275
|
+
const status = await lstat(current);
|
|
276
|
+
if (status.isSymbolicLink()) {
|
|
277
|
+
projectFailure("PROJECT_SYMLINK_TRAVERSAL", projectId, "Project path traversal encountered a symbolic link.", manifestLocation());
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
catch (error) {
|
|
281
|
+
if (allowMissing && isErrorCode(error, "ENOENT"))
|
|
282
|
+
return;
|
|
283
|
+
if (error instanceof SemantifoldDiagnostic)
|
|
284
|
+
throw error;
|
|
285
|
+
projectFailure("PROJECT_SOURCE_READ_FAILED", projectId, "Declared project path could not be inspected.", manifestLocation(), error);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Requires one real regular file.
|
|
291
|
+
* @param {string} filename - Absolute file path.
|
|
292
|
+
* @param {string} displayPath - Stable diagnostic filename.
|
|
293
|
+
* @param {string} code - Diagnostic code.
|
|
294
|
+
* @param {string} [projectId] - Project identity.
|
|
295
|
+
* @returns {Promise<import("node:fs").Stats>} File status.
|
|
296
|
+
*/
|
|
297
|
+
async function requireRegularFile(filename, displayPath, code, projectId = "project") {
|
|
298
|
+
try {
|
|
299
|
+
const status = await lstat(filename);
|
|
300
|
+
if (status.isSymbolicLink()) {
|
|
301
|
+
projectFailure("PROJECT_SYMLINK_TRAVERSAL", projectId, "Declared project file must not be a symbolic link.", sourceLocation(displayPath));
|
|
302
|
+
}
|
|
303
|
+
if (!status.isFile())
|
|
304
|
+
projectFailure(code, projectId, "Declared project file must be a regular file.", sourceLocation(displayPath));
|
|
305
|
+
return status;
|
|
306
|
+
}
|
|
307
|
+
catch (error) {
|
|
308
|
+
if (error instanceof SemantifoldDiagnostic)
|
|
309
|
+
throw error;
|
|
310
|
+
projectFailure(code, projectId, "Declared project file could not be inspected.", sourceLocation(displayPath), error);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Checks whether two validated POSIX-relative paths overlap portably.
|
|
315
|
+
* @param {string} left - First path.
|
|
316
|
+
* @param {string} right - Second path.
|
|
317
|
+
* @returns {boolean} Whether either path contains the other.
|
|
318
|
+
*/
|
|
319
|
+
function portablePathsOverlap(left, right) {
|
|
320
|
+
const leftKey = left.toLowerCase();
|
|
321
|
+
const rightKey = right.toLowerCase();
|
|
322
|
+
return leftKey == rightKey || leftKey.startsWith(`${rightKey}/`) || rightKey.startsWith(`${leftKey}/`);
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Checks for an ordinary string-keyed object.
|
|
326
|
+
* @param {unknown} value - Candidate value.
|
|
327
|
+
* @returns {value is Record<string, unknown>} Whether the value is a plain object.
|
|
328
|
+
*/
|
|
329
|
+
function isPlainObject(value) {
|
|
330
|
+
return typeof value == "object" && value != null && !Array.isArray(value) && Object.getPrototypeOf(value) == Object.prototype;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Checks for a dense array without extra enumerable keys.
|
|
334
|
+
* @param {unknown} value - Candidate value.
|
|
335
|
+
* @returns {value is unknown[]} Whether the value is a dense array.
|
|
336
|
+
*/
|
|
337
|
+
function isDenseArray(value) {
|
|
338
|
+
return Array.isArray(value) && Object.keys(value).every((key, index) => key == String(index));
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Checks an object's exact closed key set.
|
|
342
|
+
* @param {Record<string, unknown>} value - Candidate object.
|
|
343
|
+
* @param {readonly string[]} keys - Required exact keys.
|
|
344
|
+
* @returns {boolean} Whether the key set is exact.
|
|
345
|
+
*/
|
|
346
|
+
function hasExactKeys(value, keys) {
|
|
347
|
+
const actual = Object.keys(value).sort();
|
|
348
|
+
const expected = [...keys].sort();
|
|
349
|
+
return actual.length == expected.length && actual.every((key, index) => key == expected[index]);
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Checks exact required fields plus an optional closed field set.
|
|
353
|
+
* @param {Record<string, unknown>} value - Candidate record.
|
|
354
|
+
* @param {readonly string[]} required - Required fields.
|
|
355
|
+
* @param {readonly string[]} optional - Optional fields.
|
|
356
|
+
* @returns {boolean} Whether the shape is exact.
|
|
357
|
+
*/
|
|
358
|
+
function hasRequiredAndOptionalKeys(value, required, optional) {
|
|
359
|
+
const actual = Object.keys(value);
|
|
360
|
+
return required.every(key => actual.includes(key)) && actual.every(key => required.includes(key) || optional.includes(key));
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Creates the stable manifest boundary location.
|
|
364
|
+
* @returns {import("./semantic/types.js").SourceLocation} Manifest location.
|
|
365
|
+
*/
|
|
366
|
+
function manifestLocation() {
|
|
367
|
+
return sourceLocation("semantifold.json");
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Creates a stable project-relative file location.
|
|
371
|
+
* @param {string} filename - Project-relative filename.
|
|
372
|
+
* @returns {import("./semantic/types.js").SourceLocation} Start-of-file location.
|
|
373
|
+
*/
|
|
374
|
+
function sourceLocation(filename) {
|
|
375
|
+
const point = { column: 1, line: 1, offset: 0 };
|
|
376
|
+
return { end: point, filename, start: point };
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Checks one narrowed filesystem error code.
|
|
380
|
+
* @param {unknown} error - Opaque failure.
|
|
381
|
+
* @param {string} code - Expected code.
|
|
382
|
+
* @returns {boolean} Whether the code matches.
|
|
383
|
+
*/
|
|
384
|
+
function isErrorCode(error, code) {
|
|
385
|
+
return error instanceof Error && "code" in error && error.code == code;
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Throws one stable located project diagnostic.
|
|
389
|
+
* @param {string} code - Stable diagnostic code.
|
|
390
|
+
* @param {string} language - Project or registration identity.
|
|
391
|
+
* @param {string} message - Stable detail.
|
|
392
|
+
* @param {import("./semantic/types.js").SourceLocation} [location] - Project-relative location.
|
|
393
|
+
* @param {unknown} [error] - Preserved cause.
|
|
394
|
+
* @returns {never} Always throws.
|
|
395
|
+
*/
|
|
396
|
+
function projectFailure(code, language, message, location, error) {
|
|
397
|
+
throw new SemantifoldDiagnostic({
|
|
398
|
+
cause: error instanceof Error ? error : undefined,
|
|
399
|
+
code,
|
|
400
|
+
language,
|
|
401
|
+
location,
|
|
402
|
+
message
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* @typedef NormalizedProjectSource
|
|
407
|
+
* @property {string} absolutePath - Canonical project-absolute file path.
|
|
408
|
+
* @property {boolean} entry - Whether this is the sole entry module.
|
|
409
|
+
* @property {string} id - Stable semantic module identity.
|
|
410
|
+
* @property {import("./semantic/types.js").SemanticLanguage} language - Registered source language.
|
|
411
|
+
* @property {string} path - Canonical project-relative file path.
|
|
412
|
+
*/
|
|
413
|
+
/**
|
|
414
|
+
* @typedef NormalizedProjectTarget
|
|
415
|
+
* @property {string} buildProjection - Generation-relative reserved build projection.
|
|
416
|
+
* @property {string} id - Stable project target identity.
|
|
417
|
+
* @property {import("./semantic/types.js").BackendLanguage} language - Registered target identity.
|
|
418
|
+
* @property {import("./semantic/types.js").PublicationTargetRole} role - Explicit target role.
|
|
419
|
+
* @property {string} sourceProjection - Generation-relative generated-source projection.
|
|
420
|
+
*/
|
|
421
|
+
/**
|
|
422
|
+
* @typedef NormalizedProject
|
|
423
|
+
* @property {string} entryModule - Sole entry module identity.
|
|
424
|
+
* @property {string} id - Stable project identity.
|
|
425
|
+
* @property {string} manifestPath - Canonical absolute manifest path.
|
|
426
|
+
* @property {string} manifestText - Exact validated manifest text.
|
|
427
|
+
* @property {string} projectRoot - Canonical absolute project root.
|
|
428
|
+
* @property {string} publicationRoot - Canonical absolute publication root.
|
|
429
|
+
* @property {NormalizedProjectSource[]} sources - Ordered normalized sources.
|
|
430
|
+
* @property {NormalizedProjectTarget[]} targets - Ordered normalized targets.
|
|
431
|
+
*/
|
|
432
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvamVjdC1tYW5pZmVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wcm9qZWN0LW1hbmlmZXN0LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEVBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQTtBQUMxRCxPQUFPLElBQUksTUFBTSxXQUFXLENBQUE7QUFDNUIsT0FBTyxFQUNMLGdDQUFnQyxFQUNoQyw4QkFBOEIsRUFDOUIsa0JBQWtCLEVBQ2xCLGdCQUFnQixFQUNqQixNQUFNLG9CQUFvQixDQUFBO0FBQzNCLE9BQU8sRUFBQywyQkFBMkIsRUFBQyxNQUFNLHVCQUF1QixDQUFBO0FBQ2pFLE9BQU8sRUFBQyxxQkFBcUIsRUFBQyxNQUFNLGlCQUFpQixDQUFBO0FBQ3JELE9BQU8sRUFBQyw2QkFBNkIsRUFBQyxNQUFNLHdCQUF3QixDQUFBO0FBQ3BFLE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLHdCQUF3QixDQUFBO0FBRXZELE1BQU0sc0JBQXNCLEdBQUcsb0JBQW9CLENBQUE7QUFDbkQsTUFBTSxxQkFBcUIsR0FBRyw0Q0FBNEMsQ0FBQTtBQUMxRSxNQUFNLFdBQVcsR0FBRyxJQUFJLEdBQUcsQ0FBQztJQUMxQixDQUFDLE1BQU0sRUFBRSxhQUFhLENBQUM7SUFDdkIsQ0FBQyxRQUFRLEVBQUUsZUFBZSxDQUFDO0lBQzNCLENBQUMsYUFBYSxFQUFFLG9CQUFvQixDQUFDO0NBQ3RDLENBQUMsQ0FBQTtBQUNGLE1BQU0saUNBQWlDLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQTtBQUN6RSxNQUFNLGFBQWEsR0FBRyxDQUFDLElBQUksRUFBRSxpQkFBaUIsRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQTtBQUMxRixNQUFNLFlBQVksR0FBRyxDQUFD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QUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLElBQUksTUFBTSxDQUFDLFNBQVMsQ0FBQTtBQUMvSCxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQVMsWUFBWSxDQUFDLEtBQUs7SUFDekIsT0FBTyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsR0FBRyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFBO0FBQy9GLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQVMsWUFBWSxDQUFDLEtBQUssRUFBRSxJQUFJO0lBQy9CLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUE7SUFDeEMsTUFBTSxRQUFRLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFBO0lBRWpDLE9BQU8sTUFBTSxDQUFDLE1BQU0sSUFBSSxRQUFRLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxHQUFHLElBQUksUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUE7QUFDakcsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILFNBQVMsMEJBQTBCLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxRQUFRO0lBQzNELE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7SUFFakMsT0FBTyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLFFBQVEsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQTtBQUM3SCxDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBUyxnQkFBZ0I7SUFDdkIsT0FBTyxjQUFjLENBQUMsa0JBQWtCLENBQUMsQ0FBQTtBQUMzQyxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQVMsY0FBYyxDQUFDLFFBQVE7SUFDOUIsTUFBTSxLQUFLLEdBQUcsRUFBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBQyxDQUFBO0lBRTdDLE9BQU8sRUFBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFDLENBQUE7QUFDN0MsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsU0FBUyxXQUFXLENBQUMsS0FBSyxFQUFFLElBQUk7SUFDOUIsT0FBTyxLQUFLLFlBQVksS0FBSyxJQUFJLE1BQU0sSUFBSSxLQUFLLElBQUksS0FBSyxDQUFDLElBQUksSUFBSSxJQUFJLENBQUE7QUFDeEUsQ0FBQztBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsU0FBUyxjQUFjLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLEtBQUs7SUFDOUQsTUFBTSxJQUFJLHFCQUFxQixDQUFDO1FBQzlCLEtBQUssRUFBRSxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFNBQVM7UUFDakQsSUFBSTtRQUNKLFFBQVE7UUFDUixRQUFRO1FBQ1IsT0FBTztLQUNSLENBQUMsQ0FBQTtBQUNKLENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBRUg7Ozs7Ozs7R0FPRztBQUVIOzs7Ozs7Ozs7O0dBVUciLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IHtsc3RhdCwgcmVhZEZpbGUsIHJlYWxwYXRofSBmcm9tIFwibm9kZTpmcy9wcm9taXNlc1wiXG5pbXBvcnQgcGF0aCBmcm9tIFwibm9kZTpwYXRoXCJcbmltcG9ydCB7XG4gIGZpbmRQb3J0YWJsZUFydGlmYWN0UGF0aENvbmZsaWN0LFxuICBmaW5kUG9ydGFibGVTb3VyY2VQYXRoQ29uZmxpY3QsXG4gIGlzU2FmZUFydGlmYWN0UGF0aCxcbiAgaXNTYWZlU291cmNlUGF0aFxufSBmcm9tIFwiLi9hcnRpZmFjdC1wYXRoLmpzXCJcbmltcG9ydCB7c3VwcG9ydHNQcm9ncmFtQXJ0aWZhY3RSb2xlfSBmcm9tIFwiLi9iYWNrZW5kcy9wcm9ncmFtLmpzXCJcbmltcG9ydCB7U2VtYW50aWZvbGREaWFnbm9zdGljfSBmcm9tIFwiLi9kaWFnbm9zdGljLmpzXCJcbmltcG9ydCB7c3VwcG9ydHNQcm9ncmFtU291cmNlTGFuZ3VhZ2V9IGZyb20gXCIuL2Zyb250ZW5kcy9wcm9ncmFtLmpzXCJcbmltcG9ydCB7bGFuZ3VhZ2VSZWdpc3RyeX0gZnJvbSBcIi4vbGFuZ3VhZ2UtcmVnaXN0cnkuanNcIlxuXG5jb25zdCBwcm9qZWN0SWRlbnRpdHlQYXR0ZXJuID0gL15bYS16XVthLXowLTktXSokL3VcbmNvbnN0IG1vZHVsZUlkZW50aXR5UGF0dGVybiA9IC9eW2Etel1bYS16MC05X10qKD86Wy4tXVthLXpdW2EtejAtOV9dKikqJC91XG5jb25zdCBzb3VyY2VSb2xlcyA9IG5ldyBNYXAoW1xuICBbXCJ0ZXh0XCIsIFwidGV4dEJhY2tlbmRcIl0sXG4gIFtcImJpbmFyeVwiLCBcImJpbmFyeUJhY2tlbmRcIl0sXG4gIFtcImFwcGxpY2F0aW9uXCIsIFwiYXBwbGljYXRpb25CYWNrZW5kXCJdXG5dKVxuY29uc3QgbWFuaWZlc3REZWZhdWx0QXBwbGljYXRpb25UYXJnZXRzID0gbmV3IFNldChbXCJhbmRyb2lkXCIsIFwiZmx1dHRlclwiXSlcbmNvbnN0IHByb2plY3RGaWVsZHMgPSBbXCJpZFwiLCBcInB1YmxpY2F0aW9uUm9vdFwiLCBcInNjaGVtYVwiLCBcInNvdXJjZXNcIiwgXCJ0YXJnZXRzXCIsIFwidmVyc2lvblwiXVxuY29uc3Qgc291cmNlRmllbGRzID0gW1wiZW50cnlcIiwgXCJpZFwiLCBcImxhbmd1YWdlXCIsIFwicGF0aFwiXVxuY29uc3QgdGFyZ2V0UmVxdWlyZWRGaWVsZHMgPSBbXCJpZFwiLCBcImxhbmd1YWdlXCIsIFwicm9sZVwiLCBcInNvdXJjZVByb2plY3Rpb25cIl1cbmNvbnN0IHRhcmdldE9wdGlvbmFsRmllbGRzID0gW1wiYnVpbGRQcm9qZWN0aW9uXCJdXG5cbi8qKlxuICogT25lIHZhbGlkYXRlZCBpbW11dGFibGUgU2VtYW50aWZvbGQgcHJvamVjdCByZXF1ZXN0LlxuICovXG5leHBvcnQgY2xhc3MgU2VtYW50aWZvbGRQcm9qZWN0IHtcbiAgLyoqXG4gICAqIENvbnN0cnVjdHMgYSB0cnVzdGVkIG5vcm1hbGl6ZWQgcHJvamVjdCB2YWx1ZSBmb3IgdGhlIG1hbmlmZXN0IGxvYWRlci5cbiAgICogQHBhcmFtIHtOb3JtYWxpemVkUHJvamVjdH0gdmFsdWUgLSBWYWxpZGF0ZWQgbm9ybWFsaXplZCBmaWVsZHMuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih2YWx1ZSkge1xuICAgIHRoaXMuZW50cnlNb2R1bGUgPSB2YWx1ZS5lbnRyeU1vZHVsZVxuICAgIHRoaXMuaWQgPSB2YWx1ZS5pZFxuICAgIHRoaXMubWFuaWZlc3RQYXRoID0gdmFsdWUubWFuaWZlc3RQYXRoXG4gICAgdGhpcy5tYW5pZmVzdFRleHQgPSB2YWx1ZS5tYW5pZmVzdFRleHRcbiAgICB0aGlzLnByb2plY3RSb290ID0gdmFsdWUucHJvamVjdFJvb3RcbiAgICB0aGlzLnB1YmxpY2F0aW9uUm9vdCA9IHZhbHVlLnB1YmxpY2F0aW9uUm9vdFxuICAgIHRoaXMuc291cmNlcyA9IE9iamVjdC5mcmVlemUodmFsdWUuc291cmNlcy5tYXAoc291cmNlID0+IE9iamVjdC5mcmVlemUoey4uLnNvdXJjZX0pKSlcbiAgICB0aGlzLnRhcmdldHMgPSBPYmplY3QuZnJlZXplKHZhbHVlLnRhcmdldHMubWFwKHRhcmdldCA9PiBPYmplY3QuZnJlZXplKHsuLi50YXJnZXR9KSkpXG4gICAgdGhpcy52ZXJzaW9uID0gLyoqIEB0eXBlIHtjb25zdH0gKi8gKDEpXG4gICAgT2JqZWN0LmZyZWV6ZSh0aGlzKVxuICB9XG59XG5cbi8qKlxuICogTG9hZHMgYW5kIHZhbGlkYXRlcyB0aGUgc3RyaWN0IHZlcnNpb25lZCBwcm9qZWN0LW1hbmlmZXN0IGJvdW5kYXJ5LlxuICovXG5leHBvcnQgY2xhc3MgUHJvamVjdE1hbmlmZXN0TG9hZGVyIHtcbiAgLyoqXG4gICAqIExvYWRzIG9uZSBwcm9qZWN0IG1hbmlmZXN0IHdpdGhvdXQgcmVhZGluZyBzb3VyY2UgY29udGVudC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtwcm9qZWN0UGF0aF0gLSBNYW5pZmVzdCBwYXRoLCByZWxhdGl2ZSB0byB0aGUgcHJvY2VzcyB3b3JraW5nIGRpcmVjdG9yeSBvciBhYnNvbHV0ZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8U2VtYW50aWZvbGRQcm9qZWN0Pn0gSW1tdXRhYmxlIG5vcm1hbGl6ZWQgcHJvamVjdC5cbiAgICovXG4gIGFzeW5jIGxvYWQocHJvamVjdFBhdGggPSBcIi4vc2VtYW50aWZvbGQuanNvblwiKSB7XG4gICAgaWYgKHR5cGVvZiBwcm9qZWN0UGF0aCAhPSBcInN0cmluZ1wiIHx8IHByb2plY3RQYXRoLmxlbmd0aCA9PSAwIHx8IHByb2plY3RQYXRoLmluY2x1ZGVzKFwiXFwwXCIpKSB7XG4gICAgICBwcm9qZWN0RmFpbHVyZShcIklOVkFMSURfUFJPSkVDVF9NQU5JRkVTVFwiLCBcInByb2plY3RcIiwgXCJQcm9qZWN0IG1hbmlmZXN0IHBhdGggbXVzdCBiZSBhIG5vbi1lbXB0eSBwYXRoIHN0cmluZy5cIilcbiAgICB9XG4gICAgY29uc3QgbWFuaWZlc3RQYXRoID0gcGF0aC5yZXNvbHZlKHByb2plY3RQYXRoKVxuICAgIGNvbnN0IHByb2plY3RSb290ID0gcGF0aC5kaXJuYW1lKG1hbmlmZXN0UGF0aClcblxuICAgIGF3YWl0IHJlcXVpcmVDYW5vbmljYWxQcm9qZWN0Um9vdChwcm9qZWN0Um9vdClcbiAgICBhd2FpdCByZXF1aXJlUmVndWxhckZpbGUobWFuaWZlc3RQYXRoLCBcInNlbWFudGlmb2xkLmpzb25cIiwgXCJQUk9KRUNUX01BTklGRVNUX1JFQURfRkFJTEVEXCIpXG4gICAgbGV0IGJ5dGVzXG5cbiAgICB0cnkge1xuICAgICAgYnl0ZXMgPSBhd2FpdCByZWFkRmlsZShtYW5pZmVzdFBhdGgpXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHByb2plY3RGYWlsdXJlKFwiUFJPSkVDVF9NQU5JRkVTVF9SRUFEX0ZBSUxFRFwiLCBcInByb2plY3RcIiwgXCJQcm9qZWN0IG1hbmlmZXN0IGNvdWxkIG5vdCBiZSByZWFkLlwiLCBtYW5pZmVzdExvY2F0aW9uKCksIGVycm9yKVxuICAgIH1cbiAgICBsZXQgbWFuaWZlc3RUZXh0XG5cbiAgICB0cnkge1xuICAgICAgbWFuaWZlc3RUZXh0ID0gbmV3IFRleHREZWNvZGVyKFwidXRmLThcIiwge2ZhdGFsOiB0cnVlfSkuZGVjb2RlKGJ5dGVzKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBwcm9qZWN0RmFpbHVyZShcIklOVkFMSURfUFJPSkVDVF9NQU5JRkVTVFwiLCBcInByb2plY3RcIiwgXCJQcm9qZWN0IG1hbmlmZXN0IG11c3QgYmUgdmFsaWQgVVRGLTguXCIsIG1hbmlmZXN0TG9jYXRpb24oKSwgZXJyb3IpXG4gICAgfVxuICAgIGxldCBjYW5kaWRhdGVcblxuICAgIHRyeSB7XG4gICAgICBjYW5kaWRhdGUgPSBKU09OLnBhcnNlKG1hbmlmZXN0VGV4dClcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcHJvamVjdEZhaWx1cmUoXCJJTlZBTElEX1BST0pFQ1RfTUFOSUZFU1RcIiwgXCJwcm9qZWN0XCIsIFwiUHJvamVjdCBtYW5pZmVzdCBtdXN0IGNvbnRhaW4gdmFsaWQgSlNPTi5cIiwgbWFuaWZlc3RMb2NhdGlvbigpLCBlcnJvcilcbiAgICB9XG5cbiAgICByZXR1cm4gbm9ybWFsaXplUHJvamVjdChjYW5kaWRhdGUsIHttYW5pZmVzdFBhdGgsIG1hbmlmZXN0VGV4dCwgcHJvamVjdFJvb3R9KVxuICB9XG59XG5cbi8qKlxuICogVmFsaWRhdGVzIGFuZCBub3JtYWxpemVzIG9uZSBwYXJzZWQgbWFuaWZlc3QuXG4gKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIFBhcnNlZCBKU09OIHZhbHVlLlxuICogQHBhcmFtIHt7bWFuaWZlc3RQYXRoOiBzdHJpbmcsIG1hbmlmZXN0VGV4dDogc3RyaW5nLCBwcm9qZWN0Um9vdDogc3RyaW5nfX0gY29udGV4dCAtIENhbm9uaWNhbCBtYW5pZmVzdCBjb250ZXh0LlxuICogQHJldHVybnMge1Byb21pc2U8U2VtYW50aWZvbGRQcm9qZWN0Pn0gSW1tdXRhYmxlIHByb2plY3QgdmFsdWUuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIG5vcm1hbGl6ZVByb2plY3QoY2FuZGlkYXRlLCBjb250ZXh0KSB7XG4gIGlmICghaXNQbGFpbk9iamVjdChjYW5kaWRhdGUpIHx8ICFoYXNFeGFjdEtleXMoY2FuZGlkYXRlLCBwcm9qZWN0RmllbGRzKSkge1xuICAgIHByb2plY3RGYWlsdXJlKFwiSU5WQUxJRF9QUk9KRUNUX01BTklGRVNUXCIsIFwicHJvamVjdFwiLCBcIlByb2plY3QgbWFuaWZlc3QgcmVxdWlyZXMgZXhhY3RseSB0aGUgdmVyc2lvbi0xIHJvb3QgZmllbGRzLlwiLCBtYW5pZmVzdExvY2F0aW9uKCkpXG4gIH1cbiAgY29uc3Qge2lkLCBwdWJsaWNhdGlvblJvb3QsIHNjaGVtYSwgc291cmNlcywgdGFyZ2V0cywgdmVyc2lvbn0gPSBjYW5kaWRhdGVcblxuICBpZiAoc2NoZW1hICE9IFwiU2VtYW50aWZvbGRQcm9qZWN0XCIgfHwgdmVyc2lvbiAhPSAxKSB7XG4gICAgcHJvamVjdEZhaWx1cmUoXCJJTlZBTElEX1BST0pFQ1RfTUFOSUZFU1RcIiwgdHlwZW9mIGlkID09IFwic3RyaW5nXCIgPyBpZCA6IFwicHJvamVjdFwiLFxuICAgICAgXCJQcm9qZWN0IG1hbmlmZXN0IHJlcXVpcmVzIHNjaGVtYSAnU2VtYW50aWZvbGRQcm9qZWN0JyB2ZXJzaW9uIDEuXCIsIG1hbmlmZXN0TG9jYXRpb24oKSlcbiAgfVxuICBpZiAodHlwZW9mIGlkICE9IFwic3RyaW5nXCIgfHwgIXByb2plY3RJZGVudGl0eVBhdHRlcm4udGVzdChpZCkpIHtcbiAgICBwcm9qZWN0RmFpbHVyZShcIklOVkFMSURfUFJPSkVDVF9NQU5JRkVTVFwiLCBcInByb2plY3RcIiwgXCJQcm9qZWN0IGlkZW50aXR5IG11c3QgYmUgYSBzdGFibGUgbG93ZXJjYXNlIElELlwiLCBtYW5pZmVzdExvY2F0aW9uKCkpXG4gIH1cbiAgaWYgKCFpc1NhZmVBcnRpZmFjdFBhdGgocHVibGljYXRpb25Sb290KSkge1xuICAgIHByb2plY3RGYWlsdXJlKFwiSU5WQUxJRF9QUk9KRUNUX1BBVEhcIiwgaWQsIFwiUHVibGljYXRpb24gcm9vdCBtdXN0IGJlIG9uZSBjYW5vbmljYWwgcHJvamVjdC1yZWxhdGl2ZSBwYXRoLlwiLCBtYW5pZmVzdExvY2F0aW9uKCkpXG4gIH1cbiAgaWYgKCFpc0RlbnNlQXJyYXkoc291cmNlcykgfHwgc291cmNlcy5sZW5ndGggPT0gMCkge1xuICAgIHByb2plY3RGYWlsdXJlKFwiSU5WQUxJRF9QUk9KRUNUX01BTklGRVNUXCIsIGlkLCBcIlByb2plY3Qgc291cmNlcyBtdXN0IGJlIGEgbm9uLWVtcHR5IG9yZGVyZWQgYXJyYXkuXCIsIG1hbmlmZXN0TG9jYXRpb24oKSlcbiAgfVxuICBpZiAoIWlzRGVuc2VBcnJheSh0YXJnZXRzKSB8fCB0YXJnZXRzLmxlbmd0aCA9PSAwKSB7XG4gICAgcHJvamVjdEZhaWx1cmUoXCJJTlZBTElEX1BST0pFQ1RfTUFOSUZFU1RcIiwgaWQsIFwiUHJvamVjdCB0YXJnZXRzIG11c3QgYmUgYSBub24tZW1wdHkgb3JkZXJlZCBhcnJheS5cIiwgbWFuaWZlc3RMb2NhdGlvbigpKVxuICB9XG4gIGNvbnN0IG5vcm1hbGl6ZWRQdWJsaWNhdGlvblJvb3QgPSBwYXRoLmpvaW4oY29udGV4dC5wcm9qZWN0Um9vdCwgcHVibGljYXRpb25Sb290KVxuICBjb25zdCBzb3VyY2VJZHMgPSBuZXcgU2V0KClcbiAgY29uc3Qgc291cmNlUGF0aHMgPSBbXVxuICAvKiogQHR5cGUge05vcm1hbGl6ZWRQcm9qZWN0U291cmNlW119ICovXG4gIGNvbnN0IG5vcm1hbGl6ZWRTb3VyY2VzID0gW11cbiAgbGV0IGVudHJ5TW9kdWxlXG5cbiAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHNvdXJjZXMubGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgY29uc3Qgc291cmNlID0gc291cmNlc1tpbmRleF1cblxuICAgIGlmICghaXNQbGFpbk9iamVjdChzb3VyY2UpIHx8ICFoYXNFeGFjdEtleXMoc291cmNlLCBzb3VyY2VGaWVsZHMpKSB7XG4gICAgICBwcm9qZWN0RmFpbHVyZShcIklOVkFMSURfUFJPSkVDVF9NQU5JRkVTVFwiLCBpZCwgYFNvdXJjZSAke2luZGV4fSByZXF1aXJlcyBleGFjdGx5IHBhdGgsIGxhbmd1YWdlLCBJRCwgYW5kIGVudHJ5IGZpZWxkcy5gLCBtYW5pZmVzdExvY2F0aW9uKCkpXG4gICAgfVxuICAgIGlmICh0eXBlb2Ygc291cmNlLmlkICE9IFwic3RyaW5nXCIgfHwgIW1vZHVsZUlkZW50aXR5UGF0dGVybi50ZXN0KHNvdXJjZS5pZCkgfHwgc291cmNlSWRzLmhhcyhzb3VyY2UuaWQpKSB7XG4gICAgICBwcm9qZWN0RmFpbHVyZShcIklOVkFMSURfUFJPSkVDVF9NQU5JRkVTVFwiLCBpZCwgYFNvdXJjZSAke2luZGV4fSBoYXMgYW4gaW52YWxpZCBvciBkdXBsaWNhdGUgbW9kdWxlIGlkZW50aXR5LmAsIG1hbmlmZXN0TG9jYXRpb24oKSlcbiAgICB9XG4gICAgaWYgKCFpc1NhZmVTb3VyY2VQYXRoKHNvdXJjZS5wYXRoKSkge1xuICAgICAgcHJvamVjdEZhaWx1cmUoXCJJTlZBTElEX1BST0pFQ1RfUEFUSFwiLCBpZCwgYFNvdXJjZSAnJHtzb3VyY2UuaWR9JyBwYXRoIG11c3QgYmUgY2Fub25pY2FsIGFuZCBwcm9qZWN0LXJlbGF0aXZlLmAsIG1hbmlmZXN0TG9jYXRpb24oKSlcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBzb3VyY2UubGFuZ3VhZ2UgIT0gXCJzdHJpbmdcIikge1xuICAgICAgcHJvamVjdEZhaWx1cmUoXCJJTlZBTElEX1BST0pFQ1RfTUFOSUZFU1RcIiwgaWQsIGBTb3VyY2UgJyR7c291cmNlLmlkfScgcmVxdWlyZXMgYSByZWdpc3RlcmVkIHNvdXJjZSBsYW5ndWFnZS5gLCBtYW5pZmVzdExvY2F0aW9uKCkpXG4gICAgfVxuICAgIGxhbmd1YWdlUmVnaXN0cnkucmVzb2x2ZShzb3VyY2UubGFuZ3VhZ2UsIFwiZnJvbnRlbmRcIiwgbWFuaWZlc3RMb2NhdGlvbigpKVxuICAgIGlmICghc3VwcG9ydHNQcm9ncmFtU291cmNlTGFuZ3VhZ2Uoc291cmNlLmxhbmd1YWdlKSkge1xuICAgICAgcHJvamVjdEZhaWx1cmUoXCJVTlNVUFBPUlRFRF9QUk9KRUNUX1NPVVJDRVwiLCBzb3VyY2UubGFuZ3VhZ2UsXG4gICAgICAgIFwiUmVnaXN0ZXJlZCBmcm9udGVuZCBkb2VzIG5vdCBwYXJ0aWNpcGF0ZSBpbiB0aGUgZXhwbGljaXQgbXVsdGktZmlsZSBwcm9qZWN0IHByb2ZpbGUuXCIsIG1hbmlmZXN0TG9jYXRpb24oKSlcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBzb3VyY2UuZW50cnkgIT0gXCJib29sZWFuXCIpIHtcbiAgICAgIHByb2plY3RGYWlsdXJlKFwiSU5WQUxJRF9QUk9KRUNUX01BTklGRVNUXCIsIGlkLCBgU291cmNlICcke3NvdXJjZS5pZH0nIGVudHJ5IG11c3QgYmUgQm9vbGVhbi5gLCBtYW5pZmVzdExvY2F0aW9uKCkpXG4gICAgfVxuICAgIGlmIChzb3VyY2UuZW50cnkpIHtcbiAgICAgIGlmIChlbnRyeU1vZHVsZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHByb2plY3RGYWlsdXJlKFwiSU5WQUxJRF9QUk9KRUNUX01BTklGRVNUXCIsIGlkLCBcIlByb2plY3Qgc291cmNlcyBtdXN0IGRlY2xhcmUgZXhhY3RseSBvbmUgZW50cnkgbW9kdWxlLlwiLCBtYW5pZmVzdExvY2F0aW9uKCkpXG4gICAgICB9XG4gICAgICBlbnRyeU1vZHVsZSA9IHNvdXJjZS5pZFxuICAgIH1cbiAgICBjb25zdCBhYnNvbHV0ZVBhdGggPSBwYXRoLmpvaW4oY29udGV4dC5wcm9qZWN0Um9vdCwgc291cmNlLnBhdGgpXG5cbiAgICBpZiAocG9ydGFibGVQYXRoc092ZXJsYXAoc291cmNlLnBhdGgsIHB1YmxpY2F0aW9uUm9vdCkpIHtcbiAgICAgIHByb2plY3RGYWlsdXJlKFwiUFJPSkVDVF9TT1VSQ0VfUFVCTElDQVRJT05fT1ZFUkxBUFwiLCBpZCxcbiAgICAgICAgYFNvdXJjZSAnJHtzb3VyY2UuaWR9JyBvdmVybGFwcyB0aGUgcHVibGlzaGVyLW93bmVkIHB1YmxpY2F0aW9uIHJvb3QuYCwgbWFuaWZlc3RMb2NhdGlvbigpKVxuICAgIH1cbiAgICBzb3VyY2VJZHMuYWRkKHNvdXJjZS5pZClcbiAgICBzb3VyY2VQYXRocy5wdXNoKHNvdXJjZS5wYXRoKVxuICAgIG5vcm1hbGl6ZWRTb3VyY2VzLnB1c2goe1xuICAgICAgYWJzb2x1dGVQYXRoLFxuICAgICAgZW50cnk6IHNvdXJjZS5lbnRyeSxcbiAgICAgIGlkOiBzb3VyY2UuaWQsXG4gICAgICBsYW5ndWFnZTogLyoqIEB0eXBlIHtpbXBvcnQoXCIuL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTGFuZ3VhZ2V9ICovIChzb3VyY2UubGFuZ3VhZ2UpLFxuICAgICAgcGF0aDogc291cmNlLnBhdGhcbiAgICB9KVxuICB9XG4gIGlmIChlbnRyeU1vZHVsZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcHJvamVjdEZhaWx1cmUoXCJJTlZBTElEX1BST0pFQ1RfTUFOSUZFU1RcIiwgaWQsIFwiUHJvamVjdCBzb3VyY2VzIG11c3QgZGVjbGFyZSBleGFjdGx5IG9uZSBlbnRyeSBtb2R1bGUuXCIsIG1hbmlmZXN0TG9jYXRpb24oKSlcbiAgfVxuICBjb25zdCBzb3VyY2VDb25mbGljdCA9IGZpbmRQb3J0YWJsZVNvdXJjZVBhdGhDb25mbGljdChzb3VyY2VQYXRocylcblxuICBpZiAoc291cmNlQ29uZmxpY3QpIHtcbiAgICBwcm9qZWN0RmFpbHVyZShcIlBST0pFQ1RfU09VUkNFX0FMSUFTXCIsIGlkLCBcIlByb2plY3Qgc291cmNlIHBhdGhzIG11c3QgYmUgdW5pcXVlIHVuZGVyIHBvcnRhYmxlIGNvbXBhcmlzb24uXCIsIG1hbmlmZXN0TG9jYXRpb24oKSlcbiAgfVxuICBjb25zdCBzb3VyY2VMYW5ndWFnZXMgPSBuZXcgU2V0KG5vcm1hbGl6ZWRTb3VyY2VzLm1hcCgoe2xhbmd1YWdlfSkgPT4gbGFuZ3VhZ2UpKVxuXG4gIGlmIChzb3VyY2VMYW5ndWFnZXMuc2l6ZSAhPSAxKSB7XG4gICAgcHJvamVjdEZhaWx1cmUoXCJJTlZBTElEX1BST0pFQ1RfTUFOSUZFU1RcIiwgaWQsIFwiQSBwcm9qZWN0IG11c3QgdXNlIG9uZSBzb3VyY2UtbGFuZ3VhZ2UgY29tcGF0aWJpbGl0eSBwcm9maWxlLlwiLCBtYW5pZmVzdExvY2F0aW9uKCkpXG4gIH1cbiAgYXdhaXQgcmVxdWlyZUV4aXN0aW5nUHJvamVjdFBhdGhzKGNvbnRleHQucHJvamVjdFJvb3QsIG5vcm1hbGl6ZWRQdWJsaWNhdGlvblJvb3QsIG5vcm1hbGl6ZWRTb3VyY2VzLCBpZClcbiAgY29uc3QgdGFyZ2V0SWRzID0gbmV3IFNldCgpXG4gIC8qKiBAdHlwZSB7Tm9ybWFsaXplZFByb2plY3RUYXJnZXRbXX0gKi9cbiAgY29uc3Qgbm9ybWFsaXplZFRhcmdldHMgPSBbXVxuICAvKiogQHR5cGUge3N0cmluZ1tdfSAqL1xuICBjb25zdCBwcm9qZWN0aW9ucyA9IFtdXG5cbiAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHRhcmdldHMubGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgY29uc3QgdGFyZ2V0ID0gdGFyZ2V0c1tpbmRleF1cblxuICAgIGlmICghaXNQbGFpbk9iamVjdCh0YXJnZXQpIHx8ICFoYXNSZXF1aXJlZEFuZE9wdGlvbmFsS2V5cyh0YXJnZXQsIHRhcmdldFJlcXVpcmVkRmllbGRzLCB0YXJnZXRPcHRpb25hbEZpZWxkcykpIHtcbiAgICAgIHByb2plY3RGYWlsdXJlKFwiSU5WQUxJRF9QUk9KRUNUX01BTklGRVNUXCIsIGlkLCBgVGFyZ2V0ICR7aW5kZXh9IGNvbnRhaW5zIG1pc3Npbmcgb3IgdW5rbm93biBmaWVsZHMuYCwgbWFuaWZlc3RMb2NhdGlvbigpKVxuICAgIH1cbiAgICBpZiAodHlwZW9mIHRhcmdldC5pZCAhPSBcInN0cmluZ1wiIHx8ICFwcm9qZWN0SWRlbnRpdHlQYXR0ZXJuLnRlc3QodGFyZ2V0LmlkKSB8fCB0YXJnZXRJZHMuaGFzKHRhcmdldC5pZCkpIHtcbiAgICAgIHByb2plY3RGYWlsdXJlKFwiSU5WQUxJRF9QUk9KRUNUX01BTklGRVNUXCIsIGlkLCBgVGFyZ2V0ICR7aW5kZXh9IGhhcyBhbiBpbnZhbGlkIG9yIGR1cGxpY2F0ZSBpZGVudGl0eS5gLCBtYW5pZmVzdExvY2F0aW9uKCkpXG4gICAgfVxuICAgIGlmICh0eXBlb2YgdGFyZ2V0Lmxhbmd1YWdlICE9IFwic3RyaW5nXCIgfHwgdHlwZW9mIHRhcmdldC5yb2xlICE9IFwic3RyaW5nXCIgfHwgIXNvdXJjZVJvbGVzLmhhcyh0YXJnZXQucm9sZSkpIHtcbiAgICAgIHByb2plY3RGYWlsdXJlKFwiSU5WQUxJRF9QUk9KRUNUX01BTklGRVNUXCIsIGlkLCBgVGFyZ2V0ICcke3RhcmdldC5pZH0nIHJlcXVpcmVzIGEgcmVnaXN0ZXJlZCB0YXJnZXQgYW5kIGV4cGxpY2l0IHJvbGUuYCwgbWFuaWZlc3RMb2NhdGlvbigpKVxuICAgIH1cbiAgICBsYW5ndWFnZVJlZ2lzdHJ5LnJlc29sdmUodGFyZ2V0Lmxhbmd1YWdlLCAvKiogQHR5cGUge1widGV4dEJhY2tlbmRcIiB8IFwiYmluYXJ5QmFja2VuZFwiIHwgXCJhcHBsaWNhdGlvbkJhY2tlbmRcIn0gKi8gKHNvdXJjZVJvbGVzLmdldCh0YXJnZXQucm9sZSkpLCBtYW5pZmVzdExvY2F0aW9uKCkpXG4gICAgaWYgKCFzdXBwb3J0c1Byb2dyYW1BcnRpZmFjdFJvbGUodGFyZ2V0Lmxhbmd1YWdlLCB0YXJnZXQucm9sZSkpIHtcbiAgICAgIHByb2plY3RGYWlsdXJlKFwiVU5TVVBQT1JURURfUFJPSkVDVF9UQVJHRVRcIiwgdGFyZ2V0Lmxhbmd1YWdlLFxuICAgICAgICBgUmVnaXN0ZXJlZCB0YXJnZXQgZG9lcyBub3Qgc3VwcG9ydCAnJHt0YXJnZXQucm9sZX0nIGdlbmVyYXRpb24gZm9yIGNvbXBsZXRlIHNlbWFudGljIHByb2dyYW1zLmAsIG1hbmlmZXN0TG9jYXRpb24oKSlcbiAgICB9XG4gICAgaWYgKHRhcmdldC5yb2xlID09IFwiYXBwbGljYXRpb25cIiAmJiAhbWFuaWZlc3REZWZhdWx0QXBwbGljYXRpb25UYXJnZXRzLmhhcyh0YXJnZXQubGFuZ3VhZ2UpKSB7XG4gICAgICBwcm9qZWN0RmFpbHVyZShcIlVOU1VQUE9SVEVEX1BST0pFQ1RfVEFSR0VUXCIsIHRhcmdldC5sYW5ndWFnZSxcbiAgICAgICAgXCJQcm9qZWN0IG1hbmlmZXN0IHZlcnNpb24gMSBjYW5ub3QgZXhwcmVzcyB0aGUgdGFyZ2V0J3MgcmVxdWlyZWQgYXBwbGljYXRpb24gY29uZmlndXJhdGlvbi5cIiwgbWFuaWZlc3RMb2NhdGlvbigpKVxuICAgIH1cbiAgICBjb25zdCBidWlsZFByb2plY3Rpb24gPSB0YXJnZXQuYnVpbGRQcm9qZWN0aW9uID09PSB1bmRlZmluZWQgPyBgdGFyZ2V0cy8ke3RhcmdldC5pZH0vYnVpbGRgIDogdGFyZ2V0LmJ1aWxkUHJvamVjdGlvblxuXG4gICAgaWYgKCFpc1NhZmVBcnRpZmFjdFBhdGgodGFyZ2V0LnNvdXJjZVByb2plY3Rpb24pIHx8ICFpc1NhZmVBcnRpZmFjdFBhdGgoYnVpbGRQcm9qZWN0aW9uKSkge1xuICAgICAgcHJvamVjdEZhaWx1cmUoXCJJTlZBTElEX1BST0pFQ1RfUEFUSFwiLCBpZCwgYFRhcmdldCAnJHt0YXJnZXQuaWR9JyBwcm9qZWN0aW9ucyBtdXN0IGJlIGNhbm9uaWNhbCBnZW5lcmF0aW9uLXJlbGF0aXZlIHBhdGhzLmAsIG1hbmlmZXN0TG9jYXRpb24oKSlcbiAgICB9XG4gICAgdGFyZ2V0SWRzLmFkZCh0YXJnZXQuaWQpXG4gICAgcHJvamVjdGlvbnMucHVzaCh0YXJnZXQuc291cmNlUHJvamVjdGlvbiwgYnVpbGRQcm9qZWN0aW9uKVxuICAgIG5vcm1hbGl6ZWRUYXJnZXRzLnB1c2goe1xuICAgICAgYnVpbGRQcm9qZWN0aW9uLFxuICAgICAgaWQ6IHRhcmdldC5pZCxcbiAgICAgIGxhbmd1YWdlOiAvKiogQHR5cGUge2ltcG9ydChcIi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmFja2VuZExhbmd1YWdlfSAqLyAodGFyZ2V0Lmxhbmd1YWdlKSxcbiAgICAgIHJvbGU6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5QdWJsaWNhdGlvblRhcmdldFJvbGV9ICovICh0YXJnZXQucm9sZSksXG4gICAgICBzb3VyY2VQcm9qZWN0aW9uOiB0YXJnZXQuc291cmNlUHJvamVjdGlvblxuICAgIH0pXG4gIH1cbiAgaWYgKGZpbmRQb3J0YWJsZUFydGlmYWN0UGF0aENvbmZsaWN0KHByb2plY3Rpb25zKSkge1xuICAgIHByb2plY3RGYWlsdXJlKFwiUFJPSkVDVF9QUk9KRUNUSU9OX0NPTExJU0lPTlwiLCBpZCxcbiAgICAgIFwiVGFyZ2V0IHNvdXJjZS9idWlsZCBwcm9qZWN0aW9ucyBtdXN0IGJlIGRpc3RpbmN0IGFuZCBub24tbmVzdGVkIHVuZGVyIHBvcnRhYmxlIGNvbXBhcmlzb24uXCIsIG1hbmlmZXN0TG9jYXRpb24oKSlcbiAgfVxuICBpZiAoZmluZFBvcnRhYmxlQXJ0aWZhY3RQYXRoQ29uZmxpY3QoWy4uLnByb2plY3Rpb25zLCBcIm1hbmlmZXN0Lmpzb25cIl0pKSB7XG4gICAgcHJvamVjdEZhaWx1cmUoXCJJTlZBTElEX1BST0pFQ1RfUEFUSFwiLCBpZCxcbiAgICAgIFwiVGFyZ2V0IHNvdXJjZS9idWlsZCBwcm9qZWN0aW9ucyBtdXN0IG5vdCBvdmVybGFwIHRoZSByZXNlcnZlZCBnZW5lcmF0aW9uIG1hbmlmZXN0IHBhdGguXCIsIG1hbmlmZXN0TG9jYXRpb24oKSlcbiAgfVxuXG4gIHJldHVybiBuZXcgU2VtYW50aWZvbGRQcm9qZWN0KHtcbiAgICBlbnRyeU1vZHVsZSxcbiAgICBpZCxcbiAgICBtYW5pZmVzdFBhdGg6IGNvbnRleHQubWFuaWZlc3RQYXRoLFxuICAgIG1hbmlmZXN0VGV4dDogY29udGV4dC5tYW5pZmVzdFRleHQsXG4gICAgcHJvamVjdFJvb3Q6IGNvbnRleHQucHJvamVjdFJvb3QsXG4gICAgcHVibGljYXRpb25Sb290OiBub3JtYWxpemVkUHVibGljYXRpb25Sb290LFxuICAgIHNvdXJjZXM6IG5vcm1hbGl6ZWRTb3VyY2VzLFxuICAgIHRhcmdldHM6IG5vcm1hbGl6ZWRUYXJnZXRzXG4gIH0pXG59XG5cbi8qKlxuICogUmVxdWlyZXMgYSBjYW5vbmljYWwgcmVhbCBwcm9qZWN0IHJvb3QuXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJvamVjdFJvb3QgLSBBYnNvbHV0ZSBtYW5pZmVzdCBkaXJlY3RvcnkuXG4gKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gQ29tcGxldGlvbi5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVxdWlyZUNhbm9uaWNhbFByb2plY3RSb290KHByb2plY3RSb290KSB7XG4gIHRyeSB7XG4gICAgY29uc3QgZXhhY3QgPSBhd2FpdCByZWFscGF0aChwcm9qZWN0Um9vdClcblxuICAgIGlmIChleGFjdCAhPSBwcm9qZWN0Um9vdCkge1xuICAgICAgcHJvamVjdEZhaWx1cmUoXCJQUk9KRUNUX1NZTUxJTktfVFJBVkVSU0FMXCIsIFwicHJvamVjdFwiLCBcIlByb2plY3Qgcm9vdCBtdXN0IG5vdCBiZSByZWFjaGVkIHRocm91Z2ggYSBzeW1ib2xpYyBsaW5rLlwiLCBtYW5pZmVzdExvY2F0aW9uKCkpXG4gICAgfVxuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFNlbWFudGlmb2xkRGlhZ25vc3RpYykgdGhyb3cgZXJyb3JcbiAgICBwcm9qZWN0RmFpbHVyZShcIlBST0pFQ1RfTUFOSUZFU1RfUkVBRF9GQUlMRURcIiwgXCJwcm9qZWN0XCIsIFwiUHJvamVjdCByb290IGNvdWxkIG5vdCBiZSByZXNvbHZlZC5cIiwgbWFuaWZlc3RMb2NhdGlvbigpLCBlcnJvcilcbiAgfVxufVxuXG4vKipcbiAqIFZhbGlkYXRlcyBldmVyeSBzb3VyY2UgcGF0aCBhbmQgZXZlcnkgZXhpc3RpbmcgcHVibGljYXRpb24tcm9vdCBjb21wb25lbnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJvamVjdFJvb3QgLSBDYW5vbmljYWwgcHJvamVjdCByb290LlxuICogQHBhcmFtIHtzdHJpbmd9IHB1YmxpY2F0aW9uUm9vdCAtIE5vcm1hbGl6ZWQgcHVibGljYXRpb24gcm9vdC5cbiAqIEBwYXJhbSB7cmVhZG9ubHkgTm9ybWFsaXplZFByb2plY3RTb3VyY2VbXX0gc291cmNlcyAtIE5vcm1hbGl6ZWQgc291cmNlcy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9qZWN0SWQgLSBQcm9qZWN0IGlkZW50aXR5LlxuICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IENvbXBsZXRpb24uXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlcXVpcmVFeGlzdGluZ1Byb2plY3RQYXRocyhwcm9qZWN0Um9vdCwgcHVibGljYXRpb25Sb290LCBzb3VyY2VzLCBwcm9qZWN0SWQpIHtcbiAgYXdhaXQgcmVxdWlyZU5vU3ltbGlua0NvbXBvbmVudHMocHJvamVjdFJvb3QsIHB1YmxpY2F0aW9uUm9vdCwgcHJvamVjdElkLCB0cnVlKVxuICBjb25zdCBmaWxlSWRlbnRpdGllcyA9IG5ldyBTZXQoKVxuXG4gIGZvciAoY29uc3Qgc291cmNlIG9mIHNvdXJjZXMpIHtcbiAgICBhd2FpdCByZXF1aXJlTm9TeW1saW5rQ29tcG9uZW50cyhwcm9qZWN0Um9vdCwgc291cmNlLmFic29sdXRlUGF0aCwgcHJvamVjdElkLCBmYWxzZSlcbiAgICBjb25zdCBzdGF0dXMgPSBhd2FpdCByZXF1aXJlUmVndWxhckZpbGUoc291cmNlLmFic29sdXRlUGF0aCwgc291cmNlLnBhdGgsIFwiUFJPSkVDVF9TT1VSQ0VfUkVBRF9GQUlMRURcIiwgcHJvamVjdElkKVxuICAgIGNvbnN0IGlkZW50aXR5ID0gYCR7U3RyaW5nKHN0YXR1cy5kZXYpfToke1N0cmluZyhzdGF0dXMuaW5vKX1gXG5cbiAgICBpZiAoZmlsZUlkZW50aXRpZXMuaGFzKGlkZW50aXR5KSkge1xuICAgICAgcHJvamVjdEZhaWx1cmUoXCJQUk9KRUNUX1NPVVJDRV9BTElBU1wiLCBwcm9qZWN0SWQsIFwiUHJvamVjdCBzb3VyY2UgcGF0aHMgbXVzdCBub3QgYWxpYXMgdGhlIHNhbWUgZmlsZS5cIiwgc291cmNlTG9jYXRpb24oc291cmNlLnBhdGgpKVxuICAgIH1cbiAgICBmaWxlSWRlbnRpdGllcy5hZGQoaWRlbnRpdHkpXG4gIH1cbn1cblxuLyoqXG4gKiBSZWplY3RzIHN5bWxpbmtzIGJlbmVhdGggYSBjYW5vbmljYWwgcHJvamVjdCByb290LlxuICogQHBhcmFtIHtzdHJpbmd9IHByb2plY3RSb290IC0gQ2Fub25pY2FsIHByb2plY3Qgcm9vdC5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0YXJnZXQgLSBBYnNvbHV0ZSB0YXJnZXQuXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJvamVjdElkIC0gUHJvamVjdCBpZGVudGl0eS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gYWxsb3dNaXNzaW5nIC0gV2hldGhlciBhIG1pc3Npbmcgc3VmZml4IGlzIHBlcm1pdHRlZC5cbiAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSBDb21wbGV0aW9uLlxuICovXG5hc3luYyBmdW5jdGlvbiByZXF1aXJlTm9TeW1saW5rQ29tcG9uZW50cyhwcm9qZWN0Um9vdCwgdGFyZ2V0LCBwcm9qZWN0SWQsIGFsbG93TWlzc2luZykge1xuICBjb25zdCByZWxhdGl2ZSA9IHBhdGgucmVsYXRpdmUocHJvamVjdFJvb3QsIHRhcmdldClcbiAgbGV0IGN1cnJlbnQgPSBwcm9qZWN0Um9vdFxuXG4gIGZvciAoY29uc3QgcGFydCBvZiByZWxhdGl2ZS5zcGxpdChwYXRoLnNlcCkuZmlsdGVyKEJvb2xlYW4pKSB7XG4gICAgY3VycmVudCA9IHBhdGguam9pbihjdXJyZW50LCBwYXJ0KVxuICAgIHRyeSB7XG4gICAgICBjb25zdCBzdGF0dXMgPSBhd2FpdCBsc3RhdChjdXJyZW50KVxuXG4gICAgICBpZiAoc3RhdHVzLmlzU3ltYm9saWNMaW5rKCkpIHtcbiAgICAgICAgcHJvamVjdEZhaWx1cmUoXCJQUk9KRUNUX1NZTUxJTktfVFJBVkVSU0FMXCIsIHByb2plY3RJZCwgXCJQcm9qZWN0IHBhdGggdHJhdmVyc2FsIGVuY291bnRlcmVkIGEgc3ltYm9saWMgbGluay5cIiwgbWFuaWZlc3RMb2NhdGlvbigpKVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoYWxsb3dNaXNzaW5nICYmIGlzRXJyb3JDb2RlKGVycm9yLCBcIkVOT0VOVFwiKSkgcmV0dXJuXG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBTZW1hbnRpZm9sZERpYWdub3N0aWMpIHRocm93IGVycm9yXG4gICAgICBwcm9qZWN0RmFpbHVyZShcIlBST0pFQ1RfU09VUkNFX1JFQURfRkFJTEVEXCIsIHByb2plY3RJZCwgXCJEZWNsYXJlZCBwcm9qZWN0IHBhdGggY291bGQgbm90IGJlIGluc3BlY3RlZC5cIiwgbWFuaWZlc3RMb2NhdGlvbigpLCBlcnJvcilcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBSZXF1aXJlcyBvbmUgcmVhbCByZWd1bGFyIGZpbGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBBYnNvbHV0ZSBmaWxlIHBhdGguXG4gKiBAcGFyYW0ge3N0cmluZ30gZGlzcGxheVBhdGggLSBTdGFibGUgZGlhZ25vc3RpYyBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjb2RlIC0gRGlhZ25vc3RpYyBjb2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IFtwcm9qZWN0SWRdIC0gUHJvamVjdCBpZGVudGl0eS5cbiAqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcIm5vZGU6ZnNcIikuU3RhdHM+fSBGaWxlIHN0YXR1cy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVxdWlyZVJlZ3VsYXJGaWxlKGZpbGVuYW1lLCBkaXNwbGF5UGF0aCwgY29kZSwgcHJvamVjdElkID0gXCJwcm9qZWN0XCIpIHtcbiAgdHJ5IHtcbiAgICBjb25zdCBzdGF0dXMgPSBhd2FpdCBsc3RhdChmaWxlbmFtZSlcblxuICAgIGlmIChzdGF0dXMuaXNTeW1ib2xpY0xpbmsoKSkge1xuICAgICAgcHJvamVjdEZhaWx1cmUoXCJQUk9KRUNUX1NZTUxJTktfVFJBVkVSU0FMXCIsIHByb2plY3RJZCwgXCJEZWNsYXJlZCBwcm9qZWN0IGZpbGUgbXVzdCBub3QgYmUgYSBzeW1ib2xpYyBsaW5rLlwiLCBzb3VyY2VMb2NhdGlvbihkaXNwbGF5UGF0aCkpXG4gICAgfVxuICAgIGlmICghc3RhdHVzLmlzRmlsZSgpKSBwcm9qZWN0RmFpbHVyZShjb2RlLCBwcm9qZWN0SWQsIFwiRGVjbGFyZWQgcHJvamVjdCBmaWxlIG11c3QgYmUgYSByZWd1bGFyIGZpbGUuXCIsIHNvdXJjZUxvY2F0aW9uKGRpc3BsYXlQYXRoKSlcblxuICAgIHJldHVybiBzdGF0dXNcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBTZW1hbnRpZm9sZERpYWdub3N0aWMpIHRocm93IGVycm9yXG4gICAgcHJvamVjdEZhaWx1cmUoY29kZSwgcHJvamVjdElkLCBcIkRlY2xhcmVkIHByb2plY3QgZmlsZSBjb3VsZCBub3QgYmUgaW5zcGVjdGVkLlwiLCBzb3VyY2VMb2NhdGlvbihkaXNwbGF5UGF0aCksIGVycm9yKVxuICB9XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgdHdvIHZhbGlkYXRlZCBQT1NJWC1yZWxhdGl2ZSBwYXRocyBvdmVybGFwIHBvcnRhYmx5LlxuICogQHBhcmFtIHtzdHJpbmd9IGxlZnQgLSBGaXJzdCBwYXRoLlxuICogQHBhcmFtIHtzdHJpbmd9IHJpZ2h0IC0gU2Vjb25kIHBhdGguXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciBlaXRoZXIgcGF0aCBjb250YWlucyB0aGUgb3RoZXIuXG4gKi9cbmZ1bmN0aW9uIHBvcnRhYmxlUGF0aHNPdmVybGFwKGxlZnQsIHJpZ2h0KSB7XG4gIGNvbnN0IGxlZnRLZXkgPSBsZWZ0LnRvTG93ZXJDYXNlKClcbiAgY29uc3QgcmlnaHRLZXkgPSByaWdodC50b0xvd2VyQ2FzZSgpXG5cbiAgcmV0dXJuIGxlZnRLZXkgPT0gcmlnaHRLZXkgfHwgbGVmdEtleS5zdGFydHNXaXRoKGAke3JpZ2h0S2V5fS9gKSB8fCByaWdodEtleS5zdGFydHNXaXRoKGAke2xlZnRLZXl9L2ApXG59XG5cbi8qKlxuICogQ2hlY2tzIGZvciBhbiBvcmRpbmFyeSBzdHJpbmcta2V5ZWQgb2JqZWN0LlxuICogQHBhcmFtIHt1bmtub3dufSB2YWx1ZSAtIENhbmRpZGF0ZSB2YWx1ZS5cbiAqIEByZXR1cm5zIHt2YWx1ZSBpcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gV2hldGhlciB0aGUgdmFsdWUgaXMgYSBwbGFpbiBvYmplY3QuXG4gKi9cbmZ1bmN0aW9uIGlzUGxhaW5PYmplY3QodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSBcIm9iamVjdFwiICYmIHZhbHVlICE9IG51bGwgJiYgIUFycmF5LmlzQXJyYXkodmFsdWUpICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZih2YWx1ZSkgPT0gT2JqZWN0LnByb3RvdHlwZVxufVxuXG4vKipcbiAqIENoZWNrcyBmb3IgYSBkZW5zZSBhcnJheSB3aXRob3V0IGV4dHJhIGVudW1lcmFibGUga2V5cy5cbiAqIEBwYXJhbSB7dW5rbm93bn0gdmFsdWUgLSBDYW5kaWRhdGUgdmFsdWUuXG4gKiBAcmV0dXJucyB7dmFsdWUgaXMgdW5rbm93bltdfSBXaGV0aGVyIHRoZSB2YWx1ZSBpcyBhIGRlbnNlIGFycmF5LlxuICovXG5mdW5jdGlvbiBpc0RlbnNlQXJyYXkodmFsdWUpIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkodmFsdWUpICYmIE9iamVjdC5rZXlzKHZhbHVlKS5ldmVyeSgoa2V5LCBpbmRleCkgPT4ga2V5ID09IFN0cmluZyhpbmRleCkpXG59XG5cbi8qKlxuICogQ2hlY2tzIGFuIG9iamVjdCdzIGV4YWN0IGNsb3NlZCBrZXkgc2V0LlxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gdmFsdWUgLSBDYW5kaWRhdGUgb2JqZWN0LlxuICogQHBhcmFtIHtyZWFkb25seSBzdHJpbmdbXX0ga2V5cyAtIFJlcXVpcmVkIGV4YWN0IGtleXMuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciB0aGUga2V5IHNldCBpcyBleGFjdC5cbiAqL1xuZnVuY3Rpb24gaGFzRXhhY3RLZXlzKHZhbHVlLCBrZXlzKSB7XG4gIGNvbnN0IGFjdHVhbCA9IE9iamVjdC5rZXlzKHZhbHVlKS5zb3J0KClcbiAgY29uc3QgZXhwZWN0ZWQgPSBbLi4ua2V5c10uc29ydCgpXG5cbiAgcmV0dXJuIGFjdHVhbC5sZW5ndGggPT0gZXhwZWN0ZWQubGVuZ3RoICYmIGFjdHVhbC5ldmVyeSgoa2V5LCBpbmRleCkgPT4ga2V5ID09IGV4cGVjdGVkW2luZGV4XSlcbn1cblxuLyoqXG4gKiBDaGVja3MgZXhhY3QgcmVxdWlyZWQgZmllbGRzIHBsdXMgYW4gb3B0aW9uYWwgY2xvc2VkIGZpZWxkIHNldC5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgdW5rbm93bj59IHZhbHVlIC0gQ2FuZGlkYXRlIHJlY29yZC5cbiAqIEBwYXJhbSB7cmVhZG9ubHkgc3RyaW5nW119IHJlcXVpcmVkIC0gUmVxdWlyZWQgZmllbGRzLlxuICogQHBhcmFtIHtyZWFkb25seSBzdHJpbmdbXX0gb3B0aW9uYWwgLSBPcHRpb25hbCBmaWVsZHMuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciB0aGUgc2hhcGUgaXMgZXhhY3QuXG4gKi9cbmZ1bmN0aW9uIGhhc1JlcXVpcmVkQW5kT3B0aW9uYWxLZXlzKHZhbHVlLCByZXF1aXJlZCwgb3B0aW9uYWwpIHtcbiAgY29uc3QgYWN0dWFsID0gT2JqZWN0LmtleXModmFsdWUpXG5cbiAgcmV0dXJuIHJlcXVpcmVkLmV2ZXJ5KGtleSA9PiBhY3R1YWwuaW5jbHVkZXMoa2V5KSkgJiYgYWN0dWFsLmV2ZXJ5KGtleSA9PiByZXF1aXJlZC5pbmNsdWRlcyhrZXkpIHx8IG9wdGlvbmFsLmluY2x1ZGVzKGtleSkpXG59XG5cbi8qKlxuICogQ3JlYXRlcyB0aGUgc3RhYmxlIG1hbmlmZXN0IGJvdW5kYXJ5IGxvY2F0aW9uLlxuICogQHJldHVybnMge2ltcG9ydChcIi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IE1hbmlmZXN0IGxvY2F0aW9uLlxuICovXG5mdW5jdGlvbiBtYW5pZmVzdExvY2F0aW9uKCkge1xuICByZXR1cm4gc291cmNlTG9jYXRpb24oXCJzZW1hbnRpZm9sZC5qc29uXCIpXG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIHN0YWJsZSBwcm9qZWN0LXJlbGF0aXZlIGZpbGUgbG9jYXRpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBQcm9qZWN0LXJlbGF0aXZlIGZpbGVuYW1lLlxuICogQHJldHVybnMge2ltcG9ydChcIi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IFN0YXJ0LW9mLWZpbGUgbG9jYXRpb24uXG4gKi9cbmZ1bmN0aW9uIHNvdXJjZUxvY2F0aW9uKGZpbGVuYW1lKSB7XG4gIGNvbnN0IHBvaW50ID0ge2NvbHVtbjogMSwgbGluZTogMSwgb2Zmc2V0OiAwfVxuXG4gIHJldHVybiB7ZW5kOiBwb2ludCwgZmlsZW5hbWUsIHN0YXJ0OiBwb2ludH1cbn1cblxuLyoqXG4gKiBDaGVja3Mgb25lIG5hcnJvd2VkIGZpbGVzeXN0ZW0gZXJyb3IgY29kZS5cbiAqIEBwYXJhbSB7dW5rbm93bn0gZXJyb3IgLSBPcGFxdWUgZmFpbHVyZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjb2RlIC0gRXhwZWN0ZWQgY29kZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBXaGV0aGVyIHRoZSBjb2RlIG1hdGNoZXMuXG4gKi9cbmZ1bmN0aW9uIGlzRXJyb3JDb2RlKGVycm9yLCBjb2RlKSB7XG4gIHJldHVybiBlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmIFwiY29kZVwiIGluIGVycm9yICYmIGVycm9yLmNvZGUgPT0gY29kZVxufVxuXG4vKipcbiAqIFRocm93cyBvbmUgc3RhYmxlIGxvY2F0ZWQgcHJvamVjdCBkaWFnbm9zdGljLlxuICogQHBhcmFtIHtzdHJpbmd9IGNvZGUgLSBTdGFibGUgZGlhZ25vc3RpYyBjb2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IGxhbmd1YWdlIC0gUHJvamVjdCBvciByZWdpc3RyYXRpb24gaWRlbnRpdHkuXG4gKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIFN0YWJsZSBkZXRhaWwuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IFtsb2NhdGlvbl0gLSBQcm9qZWN0LXJlbGF0aXZlIGxvY2F0aW9uLlxuICogQHBhcmFtIHt1bmtub3dufSBbZXJyb3JdIC0gUHJlc2VydmVkIGNhdXNlLlxuICogQHJldHVybnMge25ldmVyfSBBbHdheXMgdGhyb3dzLlxuICovXG5mdW5jdGlvbiBwcm9qZWN0RmFpbHVyZShjb2RlLCBsYW5ndWFnZSwgbWVzc2FnZSwgbG9jYXRpb24sIGVycm9yKSB7XG4gIHRocm93IG5ldyBTZW1hbnRpZm9sZERpYWdub3N0aWMoe1xuICAgIGNhdXNlOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiB1bmRlZmluZWQsXG4gICAgY29kZSxcbiAgICBsYW5ndWFnZSxcbiAgICBsb2NhdGlvbixcbiAgICBtZXNzYWdlXG4gIH0pXG59XG5cbi8qKlxuICogQHR5cGVkZWYgTm9ybWFsaXplZFByb2plY3RTb3VyY2VcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBhYnNvbHV0ZVBhdGggLSBDYW5vbmljYWwgcHJvamVjdC1hYnNvbHV0ZSBmaWxlIHBhdGguXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IGVudHJ5IC0gV2hldGhlciB0aGlzIGlzIHRoZSBzb2xlIGVudHJ5IG1vZHVsZS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBpZCAtIFN0YWJsZSBzZW1hbnRpYyBtb2R1bGUgaWRlbnRpdHkuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNMYW5ndWFnZX0gbGFuZ3VhZ2UgLSBSZWdpc3RlcmVkIHNvdXJjZSBsYW5ndWFnZS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBwYXRoIC0gQ2Fub25pY2FsIHByb2plY3QtcmVsYXRpdmUgZmlsZSBwYXRoLlxuICovXG5cbi8qKlxuICogQHR5cGVkZWYgTm9ybWFsaXplZFByb2plY3RUYXJnZXRcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBidWlsZFByb2plY3Rpb24gLSBHZW5lcmF0aW9uLXJlbGF0aXZlIHJlc2VydmVkIGJ1aWxkIHByb2plY3Rpb24uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gaWQgLSBTdGFibGUgcHJvamVjdCB0YXJnZXQgaWRlbnRpdHkuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmFja2VuZExhbmd1YWdlfSBsYW5ndWFnZSAtIFJlZ2lzdGVyZWQgdGFyZ2V0IGlkZW50aXR5LlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL3NlbWFudGljL3R5cGVzLmpzXCIpLlB1YmxpY2F0aW9uVGFyZ2V0Um9sZX0gcm9sZSAtIEV4cGxpY2l0IHRhcmdldCByb2xlLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHNvdXJjZVByb2plY3Rpb24gLSBHZW5lcmF0aW9uLXJlbGF0aXZlIGdlbmVyYXRlZC1zb3VyY2UgcHJvamVjdGlvbi5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIE5vcm1hbGl6ZWRQcm9qZWN0XG4gKiBAcHJvcGVydHkge3N0cmluZ30gZW50cnlNb2R1bGUgLSBTb2xlIGVudHJ5IG1vZHVsZSBpZGVudGl0eS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBpZCAtIFN0YWJsZSBwcm9qZWN0IGlkZW50aXR5LlxuICogQHByb3BlcnR5IHtzdHJpbmd9IG1hbmlmZXN0UGF0aCAtIENhbm9uaWNhbCBhYnNvbHV0ZSBtYW5pZmVzdCBwYXRoLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IG1hbmlmZXN0VGV4dCAtIEV4YWN0IHZhbGlkYXRlZCBtYW5pZmVzdCB0ZXh0LlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHByb2plY3RSb290IC0gQ2Fub25pY2FsIGFic29sdXRlIHByb2plY3Qgcm9vdC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBwdWJsaWNhdGlvblJvb3QgLSBDYW5vbmljYWwgYWJzb2x1dGUgcHVibGljYXRpb24gcm9vdC5cbiAqIEBwcm9wZXJ0eSB7Tm9ybWFsaXplZFByb2plY3RTb3VyY2VbXX0gc291cmNlcyAtIE9yZGVyZWQgbm9ybWFsaXplZCBzb3VyY2VzLlxuICogQHByb3BlcnR5IHtOb3JtYWxpemVkUHJvamVjdFRhcmdldFtdfSB0YXJnZXRzIC0gT3JkZXJlZCBub3JtYWxpemVkIHRhcmdldHMuXG4gKi9cbiJdfQ==
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { SemantifoldDiagnostic } from "./diagnostic.js";
|
|
2
|
+
/**
|
|
3
|
+
* Emits concise human output or the deterministic Task-039 NDJSON state protocol.
|
|
4
|
+
*/
|
|
5
|
+
export declare class ProjectBuildReporter {
|
|
6
|
+
#private;
|
|
7
|
+
/**
|
|
8
|
+
* Creates a one-cycle reporter.
|
|
9
|
+
* @param {{format?: "human" | "ndjson", stderr?: WritableOutput, stdout?: WritableOutput}} [options] - Output mode and sinks.
|
|
10
|
+
*/
|
|
11
|
+
constructor(options?: {
|
|
12
|
+
format?: "human" | "ndjson";
|
|
13
|
+
stderr?: WritableOutput;
|
|
14
|
+
stdout?: WritableOutput;
|
|
15
|
+
});
|
|
16
|
+
/**
|
|
17
|
+
* Reports validated project configuration.
|
|
18
|
+
* @param {string} projectId - Stable project identity.
|
|
19
|
+
* @returns {void}
|
|
20
|
+
*/
|
|
21
|
+
projectLoaded(projectId: string): void;
|
|
22
|
+
/**
|
|
23
|
+
* Reports one stable complete source snapshot.
|
|
24
|
+
* @param {string} snapshotHash - Complete ordered snapshot hash.
|
|
25
|
+
* @returns {void}
|
|
26
|
+
*/
|
|
27
|
+
snapshotLoaded(snapshotHash: string): void;
|
|
28
|
+
/**
|
|
29
|
+
* Reports one ordered generated target.
|
|
30
|
+
* @param {import("./project-build.js").ProjectBuildTargetResult} target - Completed target result.
|
|
31
|
+
* @returns {void}
|
|
32
|
+
*/
|
|
33
|
+
targetGenerated(target: import("./project-build.js").ProjectBuildTargetResult): void;
|
|
34
|
+
/**
|
|
35
|
+
* Reports one successful target-check stage with exact process evidence.
|
|
36
|
+
* @param {{id: string, language: string, stage: import("./semantic/types.js").TargetCheckStageResult}} checked - Target and stage result.
|
|
37
|
+
* @returns {void}
|
|
38
|
+
*/
|
|
39
|
+
targetChecked(checked: {
|
|
40
|
+
id: string;
|
|
41
|
+
language: string;
|
|
42
|
+
stage: import("./semantic/types.js").TargetCheckStageResult;
|
|
43
|
+
}): void;
|
|
44
|
+
/**
|
|
45
|
+
* Emits the sole successful terminal record.
|
|
46
|
+
* @param {import("./project-build.js").ProjectBuildSuccess} result - Committed build result.
|
|
47
|
+
* @returns {void}
|
|
48
|
+
*/
|
|
49
|
+
succeeded(result: import("./project-build.js").ProjectBuildSuccess): void;
|
|
50
|
+
/**
|
|
51
|
+
* Emits the sole failed terminal record while preserving the first diagnostic.
|
|
52
|
+
* @param {unknown} failure - Build or CLI failure.
|
|
53
|
+
* @returns {void}
|
|
54
|
+
*/
|
|
55
|
+
failed(failure: unknown): void;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Normalizes an unexpected failure without replacing a Semantifold diagnostic.
|
|
59
|
+
* @param {unknown} failure - Opaque failure.
|
|
60
|
+
* @returns {SemantifoldDiagnostic} Stable diagnostic.
|
|
61
|
+
*/
|
|
62
|
+
export declare function normalizeDiagnostic(failure: unknown): SemantifoldDiagnostic;
|
|
63
|
+
/**
|
|
64
|
+
* Serializes stable public diagnostic fields without causes or host paths.
|
|
65
|
+
* @param {SemantifoldDiagnostic} diagnostic - Normalized diagnostic.
|
|
66
|
+
* @returns {Record<string, unknown>} Protocol diagnostic.
|
|
67
|
+
*/
|
|
68
|
+
export declare function diagnosticRecord(diagnostic: SemantifoldDiagnostic): Record<string, unknown>;
|
|
69
|
+
/**
|
|
70
|
+
* Formats one normalized failure with preserved nested process evidence.
|
|
71
|
+
* This helper is shared by the one-shot and watch reporters but is not a package-root API.
|
|
72
|
+
* @param {unknown} failure - Opaque or normalized failure.
|
|
73
|
+
* @param {string} heading - Human output heading without punctuation.
|
|
74
|
+
* @returns {string} Complete newline-terminated failure text.
|
|
75
|
+
*/
|
|
76
|
+
export declare function formatHumanProjectFailure(failure: unknown, heading: string): string;
|
|
77
|
+
export type WritableOutput = {
|
|
78
|
+
write: (chunk: string) => unknown;
|
|
79
|
+
};
|
|
80
|
+
/** @typedef {{write: (chunk: string) => unknown}} WritableOutput */
|
|
81
|
+
//# sourceMappingURL=project-reporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-reporter.d.ts","sourceRoot":"","sources":["../../src/project-reporter.js"],"names":[],"mappings":"AAEA,OAAO,EAAC,qBAAqB,EAAC,MAAM,iBAAiB,CAAA;AAErD;;GAEG;AACH,qBAAa,oBAAoB;;IAa/B;;;OAGG;IACH,YAAY,OAAO,AAFhB,CACF,EADU;QAAC,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;QAAC,MAAM,CAAC,EAAE,cAAc,CAAC;QAAC,MAAM,CAAC,EAAE,cAAc,CAAA;KAEjE,EAUvB;IAED;;;;OAIG;IACH,aAAa,CAAC,SAAS,EAHZ,MAGY,GAFV,IAAI,CAKhB;IAED;;;;OAIG;IACH,cAAc,CAAC,YAAY,EAHhB,MAGgB,GAFd,IAAI,CAKhB;IAED;;;;OAIG;IACH,eAAe,CAAC,MAAM,EAHX,OAAO,oBAAoB,EAAE,wBAGlB,GAFT,IAAI,CAUhB;IAED;;;;OAIG;IACH,aAAa,CAAC,OAAO,EAHV;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,qBAAqB,EAAE,sBAAsB,CAAA;KAGhF,GAFR,IAAI,CAgBhB;IAED;;;;OAIG;IACH,SAAS,CAAC,MAAM,EAHL,OAAO,oBAAoB,EAAE,mBAGxB,GAFH,IAAI,CA6BhB;IAED;;;;OAIG;IACH,MAAM,CAAC,OAAO,EAHH,OAGG,GAFD,IAAI,CAkBhB;CAiCF;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAHhC,OAGgC,GAF9B,qBAAqB,CAYjC;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAHhC,qBAGgC,GAF9B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAWnC;AA8ED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAJtC,OAIsC,EAAE,OAAO,EAH/C,MAG+C,GAF7C,MAAM,CASlB;AAcG,YAA+C,cAAc,GAAnD;IAAC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAA;CAAC,CAAgB;AAAjE,oEAAoE"}
|