@rdfc/js-runner 3.0.3 → 3.0.4-remote

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 (45) hide show
  1. package/.claude/settings.local.json +12 -0
  2. package/README.md +37 -1
  3. package/bin/runner.js +7 -1
  4. package/bin/server.js +13 -0
  5. package/examples/echo/.idea/echo.iml +9 -0
  6. package/examples/echo/.idea/misc.xml +6 -0
  7. package/examples/echo/.idea/modules.xml +8 -0
  8. package/examples/echo/.idea/vcs.xml +7 -0
  9. package/examples/echo/.swls/config.json +1 -0
  10. package/examples/echo/package-lock.json +27 -29
  11. package/examples/echo/pipeline.ttl +0 -1
  12. package/examples/echo/processors.ttl +1 -1
  13. package/examples/echo/remote_pipeline.ttl +18 -0
  14. package/examples/echo/server.ttl +5 -0
  15. package/examples/echo/untitled:/types/MyType.ttl +0 -0
  16. package/file:/home/silvius/Projects/mumo-pipeline/ldes/http_3A_2F_2Fdata.mumo.be_2Fstreams_2Fnodes_2Fdefault/root/index.trig +3 -0
  17. package/ldes/http_3A_2F_2Fdata.mumo.be_2Fstreams_2Fnodes_2Fdefault/root/index.trig +3 -0
  18. package/lib/client.d.ts +2 -1
  19. package/lib/client.js +70 -22
  20. package/lib/index.d.ts +2 -0
  21. package/lib/index.js +3 -1
  22. package/lib/jsonld.d.ts +17 -0
  23. package/lib/jsonld.js +135 -0
  24. package/lib/reader.d.ts +4 -1
  25. package/lib/reader.js +11 -3
  26. package/lib/runner.d.ts +6 -1
  27. package/lib/runner.js +43 -15
  28. package/lib/server.d.ts +9 -0
  29. package/lib/server.js +459 -0
  30. package/lib/state.d.ts +32 -0
  31. package/lib/state.js +71 -0
  32. package/lib/testUtils.d.ts +24 -0
  33. package/lib/testUtils.js +150 -0
  34. package/lib/tsconfig.tsbuildinfo +1 -1
  35. package/lib/writer.d.ts +5 -1
  36. package/lib/writer.js +26 -10
  37. package/minimal.ttl +99 -0
  38. package/package.json +12 -11
  39. package/src/client.ts +99 -24
  40. package/src/index.ts +2 -0
  41. package/src/reader.ts +11 -1
  42. package/src/runner.ts +58 -11
  43. package/src/server.ts +545 -0
  44. package/src/state.ts +105 -0
  45. package/src/writer.ts +36 -12
@@ -0,0 +1,24 @@
1
+ import { DataChunk, RunnerClient } from '@rdfc/proto';
2
+ import { ClientReadableStream } from '@grpc/grpc-js';
3
+ import winston from 'winston';
4
+ import { WriterInstance } from './writer.js';
5
+ import { ReaderInstance } from './reader.js';
6
+ import { Processor } from './processor.js';
7
+ import { FullProc } from './runner.js';
8
+ import { Quad } from '@rdfjs/types';
9
+ export declare function getProcessorShape(baseIRI?: string): Promise<import("rdf-lens").Shapes>;
10
+ export declare class TestClient extends RunnerClient {
11
+ next: (stream: ClientReadableStream<DataChunk>) => unknown;
12
+ constructor();
13
+ nextStream(): Promise<ClientReadableStream<DataChunk>>;
14
+ receiveStreamMessage(): ClientReadableStream<DataChunk>;
15
+ }
16
+ export declare function one<T>(iter: AsyncIterable<T>): Promise<T | undefined>;
17
+ export declare const client: TestClient;
18
+ export declare const uri = "someUri";
19
+ export declare const logger: winston.Logger;
20
+ export declare function createWriter(iri?: string): [WriterInstance, ReaderInstance];
21
+ export declare function createReader(iri?: string): ReaderInstance;
22
+ export declare function importFile(file: string): Promise<Quad[]>;
23
+ export declare function getProc<T extends Processor<unknown>>(config: string, ty: string, configLocation: string, uri?: string): Promise<FullProc<T>>;
24
+ export declare function checkProcDefinition(file: string, n: string): Promise<void>;
@@ -0,0 +1,150 @@
1
+ import { RunnerClient } from '@rdfc/proto';
2
+ import * as grpc from '@grpc/grpc-js';
3
+ import { ClientReadableStreamImpl } from './reexports.js';
4
+ import { extractShapes } from 'rdf-lens';
5
+ import { NamedNode, Parser, Writer } from 'n3';
6
+ import { readFile } from 'fs/promises';
7
+ import winston, { createLogger } from 'winston';
8
+ import { WriterInstance } from './writer.js';
9
+ import { ReaderInstance } from './reader.js';
10
+ import { Runner } from './runner.js';
11
+ import { createTermNamespace } from '@treecg/types';
12
+ import { expect } from 'vitest';
13
+ export async function getProcessorShape(baseIRI = process.cwd() + '/node_modules/@rdfc/js-runner/index.ttl') {
14
+ const configFile = await readFile(baseIRI, { encoding: 'utf8' });
15
+ const configQuads = new Parser().parse(configFile);
16
+ const shapes = extractShapes(configQuads);
17
+ return shapes;
18
+ }
19
+ export class TestClient extends RunnerClient {
20
+ next;
21
+ constructor() {
22
+ super('localhost:5400', grpc.credentials.createInsecure());
23
+ }
24
+ nextStream() {
25
+ return new Promise((res) => (this.next = res));
26
+ }
27
+ receiveStreamMessage() {
28
+ const stream = new ClientReadableStreamImpl((data) => {
29
+ return { data };
30
+ });
31
+ this.next(stream);
32
+ return stream;
33
+ }
34
+ }
35
+ export async function one(iter) {
36
+ for await (const item of iter) {
37
+ return item;
38
+ }
39
+ }
40
+ export const client = new TestClient();
41
+ export const uri = 'someUri';
42
+ export const logger = createLogger({
43
+ transports: new winston.transports.Console({
44
+ level: process.env['DEBUG'] || 'info',
45
+ }),
46
+ });
47
+ export function createWriter(iri = uri) {
48
+ const reader = createReader(iri);
49
+ const writeStream = new WriterInstance(iri, client, async (msg) => {
50
+ if (msg.msg) {
51
+ reader.handleMsg(msg.msg);
52
+ }
53
+ if (msg.close) {
54
+ reader.close();
55
+ }
56
+ }, logger);
57
+ return [writeStream, reader];
58
+ }
59
+ export function createReader(iri = uri) {
60
+ const reader = new ReaderInstance(iri, client, logger);
61
+ return reader;
62
+ }
63
+ const shapeQuads = `
64
+ @prefix rdfc: <https://w3id.org/rdf-connect#>.
65
+ @prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
66
+ @prefix sh: <http://www.w3.org/ns/shacl#>.
67
+ [ ] a sh:NodeShape;
68
+ sh:targetClass <JsProcessorShape>;
69
+ sh:property [
70
+ sh:path rdfc:entrypoint;
71
+ sh:name "location";
72
+ sh:minCount 1;
73
+ sh:maxCount 1;
74
+ sh:datatype xsd:string;
75
+ ], [
76
+ sh:path rdfc:file;
77
+ sh:name "file";
78
+ sh:minCount 1;
79
+ sh:maxCount 1;
80
+ sh:datatype xsd:string;
81
+ ], [
82
+ sh:path rdfc:class;
83
+ sh:name "clazz";
84
+ sh:maxCount 1;
85
+ sh:datatype xsd:string;
86
+ ].
87
+ `;
88
+ const OWL = createTermNamespace('http://www.w3.org/2002/07/owl#', 'imports');
89
+ const processorShapes = extractShapes(new Parser().parse(shapeQuads));
90
+ const base = 'https://w3id.org/rdf-connect#';
91
+ export async function importFile(file) {
92
+ const done = new Set();
93
+ const todo = [new URL('file://' + file)];
94
+ const quads = [];
95
+ let item = todo.pop();
96
+ while (item !== undefined) {
97
+ if (done.has(item.toString())) {
98
+ item = todo.pop();
99
+ continue;
100
+ }
101
+ done.add(item.toString());
102
+ if (item.protocol !== 'file:') {
103
+ throw 'No supported protocol ' + item.protocol;
104
+ }
105
+ const txt = await readFile(item.pathname, { encoding: 'utf8' });
106
+ const extras = new Parser({ baseIRI: item.toString() }).parse(txt);
107
+ for (const o of extras
108
+ .filter((x) => x.subject.value === item?.toString() &&
109
+ x.predicate.equals(OWL.imports))
110
+ .map((x) => x.object.value)) {
111
+ todo.push(new URL(o));
112
+ }
113
+ quads.push(...extras);
114
+ item = todo.pop();
115
+ }
116
+ return quads;
117
+ }
118
+ export async function getProc(config, ty, configLocation, uri = 'http://example.com/ns#processor') {
119
+ const configQuads = await importFile(configLocation);
120
+ const procConfig = processorShapes.lenses['JsProcessorShape'].execute({
121
+ id: new NamedNode(base + ty),
122
+ quads: configQuads,
123
+ });
124
+ const msgs = [];
125
+ const write = async (x) => {
126
+ msgs.push(x);
127
+ };
128
+ const runner = new Runner(new TestClient(), write, 'http://example.com/ns#', logger);
129
+ configQuads.push(...new Parser().parse(config));
130
+ await runner.handleOrchMessage({
131
+ pipeline: new Writer().quadsToString(configQuads),
132
+ });
133
+ const proc = await runner.addProcessor({
134
+ config: JSON.stringify(procConfig),
135
+ arguments: '',
136
+ uri,
137
+ });
138
+ return proc;
139
+ }
140
+ export async function checkProcDefinition(file, n) {
141
+ const quads = await importFile(file);
142
+ const procConfig = (processorShapes.lenses['JsProcessorShape'].execute({
143
+ id: new NamedNode(base + n),
144
+ quads: quads,
145
+ }));
146
+ expect(procConfig.file, n + ' has file').toBeDefined();
147
+ expect(procConfig.location, n + ' has location').toBeDefined();
148
+ expect(procConfig.clazz, n + ' has clazz').toBeDefined();
149
+ }
150
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdFV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3Rlc3RVdGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQWEsWUFBWSxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBQ3JELE9BQU8sS0FBSyxJQUFJLE1BQU0sZUFBZSxDQUFBO0FBRXJDLE9BQU8sRUFBRSx3QkFBd0IsRUFBdUIsTUFBTSxhQUFhLENBQUE7QUFDM0UsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLFVBQVUsQ0FBQTtBQUN4QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxJQUFJLENBQUE7QUFDOUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGFBQWEsQ0FBQTtBQUN0QyxPQUFPLE9BQU8sRUFBRSxFQUFFLFlBQVksRUFBRSxNQUFNLFNBQVMsQ0FBQTtBQUMvQyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sVUFBVSxDQUFBO0FBQ3pDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxVQUFVLENBQUE7QUFFekMsT0FBTyxFQUFZLE1BQU0sRUFBRSxNQUFNLFVBQVUsQ0FBQTtBQUUzQyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxlQUFlLENBQUE7QUFDbkQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLFFBQVEsQ0FBQTtBQUUvQixNQUFNLENBQUMsS0FBSyxVQUFVLGlCQUFpQixDQUNyQyxPQUFPLEdBQUcsT0FBTyxDQUFDLEdBQUcsRUFBRSxHQUFHLHlDQUF5QztJQUVuRSxNQUFNLFVBQVUsR0FBRyxNQUFNLFFBQVEsQ0FBQyxPQUFPLEVBQUUsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQTtJQUNoRSxNQUFNLFdBQVcsR0FBRyxJQUFJLE1BQU0sRUFBRSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQTtJQUNsRCxNQUFNLE1BQU0sR0FBRyxhQUFhLENBQUMsV0FBVyxDQUFDLENB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SSxHQUFHLE1BQU0sTUFBTSxDQUFDLFlBQVksQ0FBSTtRQUN4QyxNQUFNLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUM7UUFDbEMsU0FBUyxFQUFFLEVBQUU7UUFDYixHQUFHO0tBQ0osQ0FBQyxDQUFBO0lBRUYsT0FBTyxJQUFJLENBQUE7QUFDYixDQUFDO0FBRUQsTUFBTSxDQUFDLEtBQUssVUFBVSxtQkFBbUIsQ0FBQyxJQUFZLEVBQUUsQ0FBUztJQUMvRCxNQUFNLEtBQUssR0FBRyxNQUFNLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUNwQyxNQUFNLFVBQVUsR0FBb0QsQ0FDbEUsZUFBZSxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUNqRCxFQUFFLEVBQUUsSUFBSSxTQUFTLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQztRQUMzQixLQUFLLEVBQUUsS0FBSztLQUNiLENBQUMsQ0FDSCxDQUFBO0lBQ0QsTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFBO0lBQ3RELE1BQU0sQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLENBQUMsR0FBRyxlQUFlLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQTtJQUM5RCxNQUFNLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDLEdBQUcsWUFBWSxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUE7QUFDMUQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERhdGFDaHVuaywgUnVubmVyQ2xpZW50IH0gZnJvbSAnQHJkZmMvcHJvdG8nXG5pbXBvcnQgKiBhcyBncnBjIGZyb20gJ0BncnBjL2dycGMtanMnXG5pbXBvcnQgeyBDbGllbnRSZWFkYWJsZVN0cmVhbSB9IGZyb20gJ0BncnBjL2dycGMtanMnXG5pbXBvcnQgeyBDbGllbnRSZWFkYWJsZVN0cmVhbUltcGwsIE9yY2hlc3RyYXRvck1lc3NhZ2UgfSBmcm9tICcuL3JlZXhwb3J0cydcbmltcG9ydCB7IGV4dHJhY3RTaGFwZXMgfSBmcm9tICdyZGYtbGVucydcbmltcG9ydCB7IE5hbWVkTm9kZSwgUGFyc2VyLCBXcml0ZXIgfSBmcm9tICduMydcbmltcG9ydCB7IHJlYWRGaWxlIH0gZnJvbSAnZnMvcHJvbWlzZXMnXG5pbXBvcnQgd2luc3RvbiwgeyBjcmVhdGVMb2dnZXIgfSBmcm9tICd3aW5zdG9uJ1xuaW1wb3J0IHsgV3JpdGVySW5zdGFuY2UgfSBmcm9tICcuL3dyaXRlcidcbmltcG9ydCB7IFJlYWRlckluc3RhbmNlIH0gZnJvbSAnLi9yZWFkZXInXG5pbXBvcnQgeyBQcm9jZXNzb3IgfSBmcm9tICcuL3Byb2Nlc3NvcidcbmltcG9ydCB7IEZ1bGxQcm9jLCBSdW5uZXIgfSBmcm9tICcuL3J1bm5lcidcbmltcG9ydCB7IFF1YWQsIFRlcm0gfSBmcm9tICdAcmRmanMvdHlwZXMnXG5pbXBvcnQgeyBjcmVhdGVUZXJtTmFtZXNwYWNlIH0gZnJvbSAnQHRyZWVjZy90eXBlcydcbmltcG9ydCB7IGV4cGVjdCB9IGZyb20gJ3ZpdGVzdCdcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldFByb2Nlc3NvclNoYXBlKFxuICBiYXNlSVJJID0gcHJvY2Vzcy5jd2QoKSArICcvbm9kZV9tb2R1bGVzL0ByZGZjL2pzLXJ1bm5lci9pbmRleC50dGwnLFxuKSB7XG4gIGNvbnN0IGNvbmZpZ0ZpbGUgPSBhd2FpdCByZWFkRmlsZShiYXNlSVJJLCB7IGVuY29kaW5nOiAndXRmOCcgfSlcbiAgY29uc3QgY29uZmlnUXVhZHMgPSBuZXcgUGFyc2VyKCkucGFyc2UoY29uZmlnRmlsZSlcbiAgY29uc3Qgc2hhcGVzID0gZXh0cmFjdFNoYXBlcyhjb25maWdRdWFkcylcblxuICByZXR1cm4gc2hhcGVzXG59XG5cbmV4cG9ydCBjbGFzcyBUZXN0Q2xpZW50IGV4dGVuZHMgUnVubmVyQ2xpZW50IHtcbiAgbmV4dDogKHN0cmVhbTogQ2xpZW50UmVhZGFibGVTdHJlYW08RGF0YUNodW5rPikgPT4gdW5rbm93blxuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCdsb2NhbGhvc3Q6NTQwMCcsIGdycGMuY3JlZGVudGlhbHMuY3JlYXRlSW5zZWN1cmUoKSlcbiAgfVxuXG4gIG5leHRTdHJlYW0oKTogUHJvbWlzZTxDbGllbnRSZWFkYWJsZVN0cmVhbTxEYXRhQ2h1bms+PiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXMpID0+ICh0aGlzLm5leHQgPSByZXMpKVxuICB9XG5cbiAgcmVjZWl2ZVN0cmVhbU1lc3NhZ2UoKTogQ2xpZW50UmVhZGFibGVTdHJlYW08RGF0YUNodW5rPiB7XG4gICAgY29uc3Qgc3RyZWFtID0gbmV3IENsaWVudFJlYWRhYmxlU3RyZWFtSW1wbDxEYXRhQ2h1bms+KChkYXRhOiBCdWZmZXIpID0+IHtcbiAgICAgIHJldHVybiB7IGRhdGEgfVxuICAgIH0pXG4gICAgdGhpcy5uZXh0KHN0cmVhbSlcbiAgICByZXR1cm4gc3RyZWFtXG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG9uZTxUPihpdGVyOiBBc3luY0l0ZXJhYmxlPFQ+KTogUHJvbWlzZTxUIHwgdW5kZWZpbmVkPiB7XG4gIGZvciBhd2FpdCAoY29uc3QgaXRlbSBvZiBpdGVyKSB7XG4gICAgcmV0dXJuIGl0ZW1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgY2xpZW50ID0gbmV3IFRlc3RDbGllbnQoKVxuZXhwb3J0IGNvbnN0IHVyaSA9ICdzb21lVXJpJ1xuZXhwb3J0IGNvbnN0IGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcih7XG4gIHRyYW5zcG9ydHM6IG5ldyB3aW5zdG9uLnRyYW5zcG9ydHMuQ29uc29sZSh7XG4gICAgbGV2ZWw6IHByb2Nlc3MuZW52WydERUJVRyddIHx8ICdpbmZvJyxcbiAgfSksXG59KVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlV3JpdGVyKGlyaSA9IHVyaSk6IFtXcml0ZXJJbnN0YW5jZSwgUmVhZGVySW5zdGFuY2VdIHtcbiAgY29uc3QgcmVhZGVyID0gY3JlYXRlUmVhZGVyKGlyaSlcbiAgY29uc3Qgd3JpdGVTdHJlYW0gPSBuZXcgV3JpdGVySW5zdGFuY2UoXG4gICAgaXJpLFxuICAgIGNsaWVudCxcbiAgICBhc3luYyAobXNnKSA9PiB7XG4gICAgICBpZiAobXNnLm1zZykge1xuICAgICAgICByZWFkZXIuaGFuZGxlTXNnKG1zZy5tc2cpXG4gICAgICB9XG4gICAgICBpZiAobXNnLmNsb3NlKSB7XG4gICAgICAgIHJlYWRlci5jbG9zZSgpXG4gICAgICB9XG4gICAgfSxcbiAgICBsb2dnZXIsXG4gIClcbiAgcmV0dXJuIFt3cml0ZVN0cmVhbSwgcmVhZGVyXVxufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUmVhZGVyKGlyaSA9IHVyaSk6IFJlYWRlckluc3RhbmNlIHtcbiAgY29uc3QgcmVhZGVyID0gbmV3IFJlYWRlckluc3RhbmNlKGlyaSwgY2xpZW50LCBsb2dnZXIpXG4gIHJldHVybiByZWFkZXJcbn1cblxuY29uc3Qgc2hhcGVRdWFkcyA9IGBcbkBwcmVmaXggcmRmYzogPGh0dHBzOi8vdzNpZC5vcmcvcmRmLWNvbm5lY3QjPi5cbkBwcmVmaXggeHNkOiA8aHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjPi5cbkBwcmVmaXggc2g6IDxodHRwOi8vd3d3LnczLm9yZy9ucy9zaGFjbCM+LlxuWyBdIGEgc2g6Tm9kZVNoYXBlO1xuICBzaDp0YXJnZXRDbGFzcyA8SnNQcm9jZXNzb3JTaGFwZT47XG4gIHNoOnByb3BlcnR5IFtcbiAgICBzaDpwYXRoIHJkZmM6ZW50cnlwb2ludDtcbiAgICBzaDpuYW1lIFwibG9jYXRpb25cIjtcbiAgICBzaDptaW5Db3VudCAxO1xuICAgIHNoOm1heENvdW50IDE7XG4gICAgc2g6ZGF0YXR5cGUgeHNkOnN0cmluZztcbiAgXSwgW1xuICAgIHNoOnBhdGggcmRmYzpmaWxlO1xuICAgIHNoOm5hbWUgXCJmaWxlXCI7XG4gICAgc2g6bWluQ291bnQgMTtcbiAgICBzaDptYXhDb3VudCAxO1xuICAgIHNoOmRhdGF0eXBlIHhzZDpzdHJpbmc7XG4gIF0sIFtcbiAgICBzaDpwYXRoIHJkZmM6Y2xhc3M7XG4gICAgc2g6bmFtZSBcImNsYXp6XCI7XG4gICAgc2g6bWF4Q291bnQgMTtcbiAgICBzaDpkYXRhdHlwZSB4c2Q6c3RyaW5nO1xuICBdLlxuYFxuY29uc3QgT1dMID0gY3JlYXRlVGVybU5hbWVzcGFjZSgnaHR0cDovL3d3dy53My5vcmcvMjAwMi8wNy9vd2wjJywgJ2ltcG9ydHMnKVxuY29uc3QgcHJvY2Vzc29yU2hhcGVzID0gZXh0cmFjdFNoYXBlcyhuZXcgUGFyc2VyKCkucGFyc2Uoc2hhcGVRdWFkcykpXG5jb25zdCBiYXNlID0gJ2h0dHBzOi8vdzNpZC5vcmcvcmRmLWNvbm5lY3QjJ1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaW1wb3J0RmlsZShmaWxlOiBzdHJpbmcpOiBQcm9taXNlPFF1YWRbXT4ge1xuICBjb25zdCBkb25lID0gbmV3IFNldDxzdHJpbmc+KClcbiAgY29uc3QgdG9kbyA9IFtuZXcgVVJMKCdmaWxlOi8vJyArIGZpbGUpXVxuICBjb25zdCBxdWFkczogUXVhZFtdID0gW11cblxuICBsZXQgaXRlbSA9IHRvZG8ucG9wKClcbiAgd2hpbGUgKGl0ZW0gIT09IHVuZGVmaW5lZCkge1xuICAgIGlmIChkb25lLmhhcyhpdGVtLnRvU3RyaW5nKCkpKSB7XG4gICAgICBpdGVtID0gdG9kby5wb3AoKVxuICAgICAgY29udGludWVcbiAgICB9XG4gICAgZG9uZS5hZGQoaXRlbS50b1N0cmluZygpKVxuICAgIGlmIChpdGVtLnByb3RvY29sICE9PSAnZmlsZTonKSB7XG4gICAgICB0aHJvdyAnTm8gc3VwcG9ydGVkIHByb3RvY29sICcgKyBpdGVtLnByb3RvY29sXG4gICAgfVxuXG4gICAgY29uc3QgdHh0ID0gYXdhaXQgcmVhZEZpbGUoaXRlbS5wYXRobmFtZSwgeyBlbmNvZGluZzogJ3V0ZjgnIH0pXG4gICAgY29uc3QgZXh0cmFzID0gbmV3IFBhcnNlcih7IGJhc2VJUkk6IGl0ZW0udG9TdHJpbmcoKSB9KS5wYXJzZSh0eHQpXG5cbiAgICBmb3IgKGNvbnN0IG8gb2YgZXh0cmFzXG4gICAgICAuZmlsdGVyKFxuICAgICAgICAoeCkgPT5cbiAgICAgICAgICB4LnN1YmplY3QudmFsdWUgPT09IGl0ZW0/LnRvU3RyaW5nKCkgJiZcbiAgICAgICAgICB4LnByZWRpY2F0ZS5lcXVhbHMoT1dMLmltcG9ydHMpLFxuICAgICAgKVxuICAgICAgLm1hcCgoeCkgPT4geC5vYmplY3QudmFsdWUpKSB7XG4gICAgICB0b2RvLnB1c2gobmV3IFVSTChvKSlcbiAgICB9XG4gICAgcXVhZHMucHVzaCguLi5leHRyYXMpXG5cbiAgICBpdGVtID0gdG9kby5wb3AoKVxuICB9XG5cbiAgcmV0dXJuIHF1YWRzXG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRQcm9jPFQgZXh0ZW5kcyBQcm9jZXNzb3I8dW5rbm93bj4+KFxuICBjb25maWc6IHN0cmluZyxcbiAgdHk6IHN0cmluZyxcbiAgY29uZmlnTG9jYXRpb246IHN0cmluZyxcbiAgdXJpID0gJ2h0dHA6Ly9leGFtcGxlLmNvbS9ucyNwcm9jZXNzb3InLFxuKTogUHJvbWlzZTxGdWxsUHJvYzxUPj4ge1xuICBjb25zdCBjb25maWdRdWFkcyA9IGF3YWl0IGltcG9ydEZpbGUoY29uZmlnTG9jYXRpb24pXG4gIGNvbnN0IHByb2NDb25maWcgPSBwcm9jZXNzb3JTaGFwZXMubGVuc2VzWydKc1Byb2Nlc3NvclNoYXBlJ10uZXhlY3V0ZSh7XG4gICAgaWQ6IG5ldyBOYW1lZE5vZGUoYmFzZSArIHR5KSxcbiAgICBxdWFkczogY29uZmlnUXVhZHMsXG4gIH0pXG5cbiAgY29uc3QgbXNnczogT3JjaGVzdHJhdG9yTWVzc2FnZVtdID0gW11cbiAgY29uc3Qgd3JpdGUgPSBhc3luYyAoeDogT3JjaGVzdHJhdG9yTWVzc2FnZSkgPT4ge1xuICAgIG1zZ3MucHVzaCh4KVxuICB9XG4gIGNvbnN0IHJ1bm5lciA9IG5ldyBSdW5uZXIoXG4gICAgbmV3IFRlc3RDbGllbnQoKSxcbiAgICB3cml0ZSxcbiAgICAnaHR0cDovL2V4YW1wbGUuY29tL25zIycsXG4gICAgbG9nZ2VyLFxuICApXG4gIGNvbmZpZ1F1YWRzLnB1c2goLi4ubmV3IFBhcnNlcigpLnBhcnNlKGNvbmZpZykpXG4gIGF3YWl0IHJ1bm5lci5oYW5kbGVPcmNoTWVzc2FnZSh7XG4gICAgcGlwZWxpbmU6IG5ldyBXcml0ZXIoKS5xdWFkc1RvU3RyaW5nKGNvbmZpZ1F1YWRzKSxcbiAgfSlcblxuICBjb25zdCBwcm9jID0gYXdhaXQgcnVubmVyLmFkZFByb2Nlc3NvcjxUPih7XG4gICAgY29uZmlnOiBKU09OLnN0cmluZ2lmeShwcm9jQ29uZmlnKSxcbiAgICBhcmd1bWVudHM6ICcnLFxuICAgIHVyaSxcbiAgfSlcblxuICByZXR1cm4gcHJvY1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY2hlY2tQcm9jRGVmaW5pdGlvbihmaWxlOiBzdHJpbmcsIG46IHN0cmluZykge1xuICBjb25zdCBxdWFkcyA9IGF3YWl0IGltcG9ydEZpbGUoZmlsZSlcbiAgY29uc3QgcHJvY0NvbmZpZyA9IDx7IGZpbGU6IFRlcm07IGxvY2F0aW9uOiBzdHJpbmc7IGNsYXp6OiBzdHJpbmcgfT4oXG4gICAgcHJvY2Vzc29yU2hhcGVzLmxlbnNlc1snSnNQcm9jZXNzb3JTaGFwZSddLmV4ZWN1dGUoe1xuICAgICAgaWQ6IG5ldyBOYW1lZE5vZGUoYmFzZSArIG4pLFxuICAgICAgcXVhZHM6IHF1YWRzLFxuICAgIH0pXG4gIClcbiAgZXhwZWN0KHByb2NDb25maWcuZmlsZSwgbiArICcgaGFzIGZpbGUnKS50b0JlRGVmaW5lZCgpXG4gIGV4cGVjdChwcm9jQ29uZmlnLmxvY2F0aW9uLCBuICsgJyBoYXMgbG9jYXRpb24nKS50b0JlRGVmaW5lZCgpXG4gIGV4cGVjdChwcm9jQ29uZmlnLmNsYXp6LCBuICsgJyBoYXMgY2xhenonKS50b0JlRGVmaW5lZCgpXG59XG4iXX0=