@fairspec/agent 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/LICENSE.md +9 -0
  2. package/README.md +3 -0
  3. package/build/actions/tableSchema/asHtml.d.ts +4 -0
  4. package/build/actions/tableSchema/asHtml.js +82 -0
  5. package/build/actions/tableSchema/asHtml.spec.d.ts +1 -0
  6. package/build/actions/tableSchema/asHtml.spec.js +356 -0
  7. package/build/actions/tableSchema/asMarkdown.d.ts +4 -0
  8. package/build/actions/tableSchema/asMarkdown.js +65 -0
  9. package/build/actions/tableSchema/asMarkdown.spec.d.ts +1 -0
  10. package/build/actions/tableSchema/asMarkdown.spec.js +133 -0
  11. package/build/document/Document.d.ts +2 -0
  12. package/build/document/Document.js +2 -0
  13. package/build/document/index.d.ts +3 -0
  14. package/build/document/index.js +3 -0
  15. package/build/document/types/Base.d.ts +3 -0
  16. package/build/document/types/Base.js +2 -0
  17. package/build/document/types/Json.d.ts +5 -0
  18. package/build/document/types/Json.js +2 -0
  19. package/build/document/validate.d.ts +5 -0
  20. package/build/document/validate.js +23 -0
  21. package/build/document/validate.spec.d.ts +1 -0
  22. package/build/document/validate.spec.js +71 -0
  23. package/build/index.d.ts +1 -0
  24. package/build/index.js +2 -0
  25. package/build/package.json +39 -0
  26. package/build/plugin.d.ts +6 -0
  27. package/build/plugin.js +15 -0
  28. package/build/schema/convert/toHtml.d.ts +4 -0
  29. package/build/schema/convert/toHtml.js +107 -0
  30. package/build/schema/convert/toHtml.spec.d.ts +1 -0
  31. package/build/schema/convert/toHtml.spec.js +432 -0
  32. package/build/schema/convert/toMarkdown.d.ts +4 -0
  33. package/build/schema/convert/toMarkdown.js +75 -0
  34. package/build/schema/convert/toMarkdown.spec.d.ts +1 -0
  35. package/build/schema/convert/toMarkdown.spec.js +137 -0
  36. package/build/schema/index.d.ts +2 -0
  37. package/build/schema/index.js +3 -0
  38. package/build/server.d.ts +2 -0
  39. package/build/server.js +29 -0
  40. package/build/tableSchema/convert/toHtml.d.ts +4 -0
  41. package/build/tableSchema/convert/toHtml.js +80 -0
  42. package/build/tableSchema/convert/toHtml.spec.d.ts +1 -0
  43. package/build/tableSchema/convert/toHtml.spec.js +375 -0
  44. package/build/tableSchema/convert/toMarkdown.d.ts +4 -0
  45. package/build/tableSchema/convert/toMarkdown.js +57 -0
  46. package/build/tableSchema/convert/toMarkdown.spec.d.ts +1 -0
  47. package/build/tableSchema/convert/toMarkdown.spec.js +141 -0
  48. package/build/tableSchema/index.d.ts +2 -0
  49. package/build/tableSchema/index.js +3 -0
  50. package/build/tools/data/validate.d.ts +971 -0
  51. package/build/tools/data/validate.js +15 -0
  52. package/build/tools/data/validate.spec.d.ts +1 -0
  53. package/build/tools/data/validate.spec.js +228 -0
  54. package/build/tools/dataSchema/infer.d.ts +797 -0
  55. package/build/tools/dataSchema/infer.js +15 -0
  56. package/build/tools/dataSchema/infer.spec.d.ts +1 -0
  57. package/build/tools/dataSchema/infer.spec.js +215 -0
  58. package/build/tools/dataSchema/validate.d.ts +177 -0
  59. package/build/tools/dataSchema/validate.js +17 -0
  60. package/build/tools/dataSchema/validate.spec.d.ts +1 -0
  61. package/build/tools/dataSchema/validate.spec.js +148 -0
  62. package/build/tools/dataset/infer.d.ts +1985 -0
  63. package/build/tools/dataset/infer.js +15 -0
  64. package/build/tools/dataset/infer.spec.d.ts +1 -0
  65. package/build/tools/dataset/infer.spec.js +181 -0
  66. package/build/tools/dataset/validate.d.ts +1168 -0
  67. package/build/tools/dataset/validate.js +17 -0
  68. package/build/tools/dataset/validate.spec.d.ts +1 -0
  69. package/build/tools/dataset/validate.spec.js +212 -0
  70. package/build/tools/dialect/infer.d.ts +889 -0
  71. package/build/tools/dialect/infer.js +16 -0
  72. package/build/tools/dialect/infer.spec.d.ts +1 -0
  73. package/build/tools/dialect/infer.spec.js +138 -0
  74. package/build/tools/table/query.d.ts +798 -0
  75. package/build/tools/table/query.js +24 -0
  76. package/build/tools/table/query.spec.d.ts +1 -0
  77. package/build/tools/table/query.spec.js +138 -0
  78. package/build/tools/table/validate.d.ts +999 -0
  79. package/build/tools/table/validate.js +16 -0
  80. package/build/tools/table/validate.spec.d.ts +1 -0
  81. package/build/tools/table/validate.spec.js +106 -0
  82. package/build/tools/tableSchema/infer.d.ts +1316 -0
  83. package/build/tools/tableSchema/infer.js +16 -0
  84. package/build/tools/tableSchema/infer.spec.d.ts +1 -0
  85. package/build/tools/tableSchema/infer.spec.js +152 -0
  86. package/build/tools/tableSchema/validate.d.ts +177 -0
  87. package/build/tools/tableSchema/validate.js +17 -0
  88. package/build/tools/tableSchema/validate.spec.d.ts +1 -0
  89. package/build/tools/tableSchema/validate.spec.js +121 -0
  90. package/package.json +39 -0
@@ -0,0 +1,432 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { convertSchemaToHtml } from "./toHtml.js";
3
+ describe("convertSchemaToHtml", () => {
4
+ it("converts a simple schema to html table", () => {
5
+ const schema = {
6
+ fields: [
7
+ {
8
+ name: "id",
9
+ type: "integer",
10
+ title: "Identifier",
11
+ description: "Unique identifier",
12
+ },
13
+ {
14
+ name: "name",
15
+ type: "string",
16
+ title: "Name",
17
+ description: "Person name",
18
+ },
19
+ ],
20
+ };
21
+ const result = convertSchemaToHtml(schema);
22
+ expect(result).toContain("<h2>Fields</h2>");
23
+ expect(result).toContain("<table>");
24
+ expect(result).toContain("<th>Name</th>");
25
+ expect(result).toContain("<th>Definition</th>");
26
+ expect(result).toContain("<th>Type</th>");
27
+ expect(result).toContain("<strong>id?</strong>");
28
+ expect(result).toContain("<strong>name?</strong>");
29
+ expect(result).toContain("<p>Unique identifier</p>");
30
+ expect(result).toContain("<p>Person name</p>");
31
+ expect(result).toContain("<code>integer</code>");
32
+ expect(result).toContain("<code>string</code>");
33
+ });
34
+ it("includes schema title and description", () => {
35
+ const schema = {
36
+ title: "Test Schema",
37
+ description: "A test schema for validation",
38
+ fields: [
39
+ {
40
+ name: "field1",
41
+ type: "string",
42
+ },
43
+ ],
44
+ };
45
+ const result = convertSchemaToHtml(schema);
46
+ expect(result).toContain('<h1 id="test-schema">Test Schema</h1>');
47
+ expect(result).toContain("<p>A test schema for validation</p>");
48
+ });
49
+ it("handles field constraints", () => {
50
+ const schema = {
51
+ fields: [
52
+ {
53
+ name: "age",
54
+ type: "integer",
55
+ constraints: {
56
+ required: true,
57
+ minimum: 0,
58
+ maximum: 120,
59
+ },
60
+ },
61
+ {
62
+ name: "email",
63
+ type: "string",
64
+ constraints: {
65
+ required: true,
66
+ pattern: "^[a-z]+@[a-z]+\\.[a-z]+$",
67
+ },
68
+ },
69
+ ],
70
+ };
71
+ const result = convertSchemaToHtml(schema);
72
+ expect(result).toContain("<strong>Constraints</strong>");
73
+ expect(result).toContain("required:");
74
+ expect(result).toContain("<code>true</code>");
75
+ expect(result).toContain("minimum:");
76
+ expect(result).toContain("<code>0</code>");
77
+ expect(result).toContain("maximum:");
78
+ expect(result).toContain("<code>120</code>");
79
+ expect(result).toContain("pattern:");
80
+ });
81
+ it("handles required field indicator", () => {
82
+ const schema = {
83
+ fields: [
84
+ {
85
+ name: "requiredField",
86
+ type: "string",
87
+ constraints: {
88
+ required: true,
89
+ },
90
+ },
91
+ {
92
+ name: "optionalField",
93
+ type: "string",
94
+ },
95
+ ],
96
+ };
97
+ const result = convertSchemaToHtml(schema);
98
+ expect(result).toContain("<strong>requiredField</strong>");
99
+ expect(result).not.toContain("requiredField?");
100
+ expect(result).toContain("<strong>optionalField?</strong>");
101
+ });
102
+ it("handles empty fields array", () => {
103
+ const schema = {
104
+ fields: [],
105
+ };
106
+ const result = convertSchemaToHtml(schema);
107
+ expect(result).toContain("<h2>Fields</h2>");
108
+ expect(result).toContain("<table>");
109
+ expect(result).toContain("</table>");
110
+ });
111
+ it("escapes HTML special characters", () => {
112
+ const schema = {
113
+ title: "Test & <Schema>",
114
+ description: 'Description with "quotes" and <tags>',
115
+ fields: [
116
+ {
117
+ name: "field",
118
+ type: "string",
119
+ description: "Description with <script>alert('xss')</script>",
120
+ },
121
+ ],
122
+ };
123
+ const result = convertSchemaToHtml(schema);
124
+ expect(result).toContain("Test &amp; &lt;Schema&gt;");
125
+ expect(result).toContain("Description with &quot;quotes&quot; and &lt;tags&gt;");
126
+ expect(result).toContain("Description with &lt;script&gt;alert(&#x27;xss&#x27;)&lt;/script&gt;");
127
+ });
128
+ it("handles fields with enum constraints", () => {
129
+ const schema = {
130
+ fields: [
131
+ {
132
+ name: "status",
133
+ type: "string",
134
+ constraints: {
135
+ enum: ["active", "inactive", "pending"],
136
+ },
137
+ },
138
+ ],
139
+ };
140
+ const result = convertSchemaToHtml(schema);
141
+ expect(result).toContain("enum:");
142
+ expect(result).toContain("<code>active, inactive, pending</code>");
143
+ });
144
+ it("handles multiple constraint types", () => {
145
+ const schema = {
146
+ fields: [
147
+ {
148
+ name: "username",
149
+ type: "string",
150
+ constraints: {
151
+ required: true,
152
+ unique: true,
153
+ minLength: 3,
154
+ maxLength: 20,
155
+ pattern: "^[a-zA-Z0-9_]+$",
156
+ },
157
+ },
158
+ ],
159
+ };
160
+ const result = convertSchemaToHtml(schema);
161
+ expect(result).toContain("required:");
162
+ expect(result).toContain("unique:");
163
+ expect(result).toContain("minLength:");
164
+ expect(result).toContain("<code>3</code>");
165
+ expect(result).toContain("maxLength:");
166
+ expect(result).toContain("<code>20</code>");
167
+ expect(result).toContain("pattern:");
168
+ });
169
+ it("handles field examples", () => {
170
+ const schema = {
171
+ fields: [
172
+ {
173
+ name: "email",
174
+ type: "string",
175
+ examples: ["user@example.com", "admin@test.org"],
176
+ },
177
+ {
178
+ name: "age",
179
+ type: "integer",
180
+ examples: [25, 30],
181
+ },
182
+ ],
183
+ };
184
+ const result = convertSchemaToHtml(schema);
185
+ expect(result).toContain("<strong>Examples</strong>");
186
+ expect(result).toContain("<code>user@example.com</code>");
187
+ expect(result).toContain("<code>admin@test.org</code>");
188
+ expect(result).toContain("<code>25</code>");
189
+ expect(result).toContain("<code>30</code>");
190
+ });
191
+ it("handles different field types", () => {
192
+ const schema = {
193
+ fields: [
194
+ { name: "field1", type: "string" },
195
+ { name: "field2", type: "integer" },
196
+ { name: "field3", type: "number" },
197
+ { name: "field4", type: "boolean" },
198
+ { name: "field5", type: "datetime" },
199
+ { name: "field6", type: "any" },
200
+ ],
201
+ };
202
+ const result = convertSchemaToHtml(schema);
203
+ expect(result).toContain("<code>string</code>");
204
+ expect(result).toContain("<code>integer</code>");
205
+ expect(result).toContain("<code>number</code>");
206
+ expect(result).toContain("<code>boolean</code>");
207
+ expect(result).toContain("<code>datetime</code>");
208
+ expect(result).toContain("<code>any</code>");
209
+ });
210
+ it("sanitizes IDs for anchors", () => {
211
+ const schema = {
212
+ title: "Test Schema & More!",
213
+ fields: [
214
+ {
215
+ name: "field-with-dashes",
216
+ type: "string",
217
+ },
218
+ {
219
+ name: "Field With Spaces",
220
+ type: "string",
221
+ },
222
+ ],
223
+ };
224
+ const result = convertSchemaToHtml(schema);
225
+ expect(result).toContain('id="test-schema-more"');
226
+ expect(result).toContain('id="field-with-dashes"');
227
+ expect(result).toContain('id="field-with-spaces"');
228
+ });
229
+ it("does not include top-level html tags", () => {
230
+ const schema = {
231
+ title: "Test",
232
+ fields: [{ name: "field1", type: "string" }],
233
+ };
234
+ const result = convertSchemaToHtml(schema);
235
+ expect(result).not.toContain("<!DOCTYPE");
236
+ expect(result).not.toContain("<html>");
237
+ expect(result).not.toContain("<head>");
238
+ expect(result).not.toContain("<body>");
239
+ expect(result).not.toContain("<style>");
240
+ });
241
+ it("handles schema without title", () => {
242
+ const schema = {
243
+ description: "Description only",
244
+ fields: [{ name: "field1", type: "string" }],
245
+ };
246
+ const result = convertSchemaToHtml(schema);
247
+ expect(result).toContain("<p>Description only</p>");
248
+ expect(result).not.toContain("<h2 id=");
249
+ expect(result).toContain("<h2>Fields</h2>");
250
+ });
251
+ it("handles field without description", () => {
252
+ const schema = {
253
+ fields: [
254
+ {
255
+ name: "field1",
256
+ type: "string",
257
+ },
258
+ ],
259
+ };
260
+ const result = convertSchemaToHtml(schema);
261
+ expect(result).toContain("<strong>field1?</strong>");
262
+ expect(result).toContain("<code>string</code>");
263
+ });
264
+ it("uses frontmatter when frontmatter option is true", () => {
265
+ const schema = {
266
+ title: "Test Schema",
267
+ description: "A test schema with frontmatter",
268
+ fields: [
269
+ {
270
+ name: "field1",
271
+ type: "string",
272
+ },
273
+ ],
274
+ };
275
+ const result = convertSchemaToHtml(schema, { frontmatter: true });
276
+ expect(result).toContain("---");
277
+ expect(result).toContain("Test Schema");
278
+ expect(result).not.toContain("<h1");
279
+ expect(result).toContain("<p>A test schema with frontmatter</p>");
280
+ });
281
+ it("uses H1 heading when frontmatter option is false or not provided", () => {
282
+ const schema = {
283
+ title: "Test Schema",
284
+ fields: [
285
+ {
286
+ name: "field1",
287
+ type: "string",
288
+ },
289
+ ],
290
+ };
291
+ const result = convertSchemaToHtml(schema, { frontmatter: false });
292
+ expect(result).toContain('<h1 id="test-schema">Test Schema</h1>');
293
+ expect(result).not.toContain("title: Test Schema");
294
+ expect(result.startsWith("<h1")).toBe(true);
295
+ });
296
+ it("handles schema with primary key", () => {
297
+ const schema = {
298
+ fields: [
299
+ {
300
+ name: "id",
301
+ type: "integer",
302
+ },
303
+ {
304
+ name: "name",
305
+ type: "string",
306
+ },
307
+ ],
308
+ primaryKey: ["id"],
309
+ };
310
+ const result = convertSchemaToHtml(schema);
311
+ expect(result).toContain("<h2>Primary Key</h2>");
312
+ expect(result).toContain("<code>id</code>");
313
+ });
314
+ it("handles schema with composite primary key", () => {
315
+ const schema = {
316
+ fields: [
317
+ {
318
+ name: "user_id",
319
+ type: "integer",
320
+ },
321
+ {
322
+ name: "project_id",
323
+ type: "integer",
324
+ },
325
+ ],
326
+ primaryKey: ["user_id", "project_id"],
327
+ };
328
+ const result = convertSchemaToHtml(schema);
329
+ expect(result).toContain("<h2>Primary Key</h2>");
330
+ expect(result).toContain("<code>user_id, project_id</code>");
331
+ });
332
+ it("handles schema with foreign keys", () => {
333
+ const schema = {
334
+ fields: [
335
+ {
336
+ name: "user_id",
337
+ type: "integer",
338
+ },
339
+ ],
340
+ foreignKeys: [
341
+ {
342
+ fields: ["user_id"],
343
+ reference: {
344
+ resource: "users",
345
+ fields: ["id"],
346
+ },
347
+ },
348
+ ],
349
+ };
350
+ const result = convertSchemaToHtml(schema);
351
+ expect(result).toContain("<h2>Foreign Keys</h2>");
352
+ expect(result).toContain("<th>Fields</th>");
353
+ expect(result).toContain("<th>Reference Resource</th>");
354
+ expect(result).toContain("<th>Reference Fields</th>");
355
+ expect(result).toContain("<code>user_id</code>");
356
+ expect(result).toContain("<code>users</code>");
357
+ expect(result).toContain("<code>id</code>");
358
+ });
359
+ it("handles schema with multiple foreign keys", () => {
360
+ const schema = {
361
+ fields: [
362
+ {
363
+ name: "user_id",
364
+ type: "integer",
365
+ },
366
+ {
367
+ name: "project_id",
368
+ type: "integer",
369
+ },
370
+ ],
371
+ foreignKeys: [
372
+ {
373
+ fields: ["user_id"],
374
+ reference: {
375
+ resource: "users",
376
+ fields: ["id"],
377
+ },
378
+ },
379
+ {
380
+ fields: ["project_id"],
381
+ reference: {
382
+ resource: "projects",
383
+ fields: ["id"],
384
+ },
385
+ },
386
+ ],
387
+ };
388
+ const result = convertSchemaToHtml(schema);
389
+ expect(result).toContain("<h2>Foreign Keys</h2>");
390
+ expect(result).toContain("<code>user_id</code>");
391
+ expect(result).toContain("<code>users</code>");
392
+ expect(result).toContain("<code>project_id</code>");
393
+ expect(result).toContain("<code>projects</code>");
394
+ });
395
+ it("handles foreign key without resource specified", () => {
396
+ const schema = {
397
+ fields: [
398
+ {
399
+ name: "parent_id",
400
+ type: "integer",
401
+ },
402
+ ],
403
+ foreignKeys: [
404
+ {
405
+ fields: ["parent_id"],
406
+ reference: {
407
+ fields: ["id"],
408
+ },
409
+ },
410
+ ],
411
+ };
412
+ const result = convertSchemaToHtml(schema);
413
+ expect(result).toContain("<h2>Foreign Keys</h2>");
414
+ expect(result).toContain("<code>parent_id</code>");
415
+ expect(result).toContain("<code>-</code>");
416
+ expect(result).toContain("<code>id</code>");
417
+ });
418
+ it("does not render primary key or foreign keys sections when not present", () => {
419
+ const schema = {
420
+ fields: [
421
+ {
422
+ name: "field1",
423
+ type: "string",
424
+ },
425
+ ],
426
+ };
427
+ const result = convertSchemaToHtml(schema);
428
+ expect(result).not.toContain("<h2>Primary Key</h2>");
429
+ expect(result).not.toContain("<h2>Foreign Keys</h2>");
430
+ });
431
+ });
432
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9IdG1sLnNwZWMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zY2hlbWEvY29udmVydC90b0h0bWwuc3BlYy50c3giXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLE1BQU0sUUFBUSxDQUFBO0FBQzdDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGFBQWMsQ0FBQTtBQUVsRCxRQUFRLENBQUMscUJBQXFCLEVBQUUsR0FBRyxFQUFFO0lBQ25DLEVBQUUsQ0FBQyx3Q0FBd0MsRUFBRSxHQUFHLEVBQUU7UUFDaEQsTUFBTSxNQUFNLEdBQVc7WUFDckIsTUFBTSxFQUFFO2dCQUNOO29CQUNFLElBQUksRUFBRSxJQUFJO29CQUNWLElBQUksRUFBRSxTQUFTO29CQUNmLEtBQUssRUFBRSxZQUFZO29CQUNuQixXQUFXLEVBQUUsbUJBQW1CO2lCQUNqQztnQkFDRDtvQkFDRSxJQUFJLEVBQUUsTUFBTTtvQkFDWixJQUFJLEVBQUUsUUFBUTtvQkFDZCxLQUFLLEVBQUUsTUFBTTtvQkFDYixXQUFXLEVBQUUsYUFBYTtpQkFDM0I7YUFDRjtTQUNGLENBQUE7UUFFRCxNQUFNLE1BQU0sR0FBRyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUUxQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsU0FBUyxDQUFDLGlCQUFpQixDQUFDLENBQUE7UUFDM0MsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQTtRQUNuQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxDQUFBO1FBQ3pDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxTQUFTLENBQUMscUJBQXFCLENBQUMsQ0FBQTtRQUMvQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxDQUFBO1FBQ3pDLE1BQU0s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b0JBQ0UsTUFBTSxFQUFFLENBQUMsV0FBVyxDQUFDO29CQUNyQixTQUFTLEVBQUU7d0JBQ1QsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDO3FCQUNmO2lCQUNGO2FBQ0Y7U0FDRixDQUFBO1FBRUQsTUFBTSxNQUFNLEdBQUcsbUJBQW1CLENBQUMsTUFBTSxDQUFDLENBQUE7UUFFMUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFNBQVMsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFBO1FBQ2pELE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxTQUFTLENBQUMsd0JBQXdCLENBQUMsQ0FBQTtRQUNsRCxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsU0FBUyxDQUFDLGdCQUFnQixDQUFDLENBQUE7UUFDMUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFNBQVMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFBO0lBQzdDLENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLHVFQUF1RSxFQUFFLEdBQUcsRUFBRTtRQUMvRSxNQUFNLE1BQU0sR0FBVztZQUNyQixNQUFNLEVBQUU7Z0JBQ047b0JBQ0UsSUFBSSxFQUFFLFFBQVE7b0JBQ2QsSUFBSSxFQUFFLFFBQVE7aUJBQ2Y7YUFDRjtTQUNGLENBQUE7UUFFRCxNQUFNLE1BQU0sR0FBRyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUUxQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFBO1FBQ3BELE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLHVCQUF1QixDQUFDLENBQUE7SUFDdkQsQ0FBQyxDQUFDLENBQUE7QUFDSixDQUFDLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgU2NoZW1hIH0gZnJvbSBcIkBmYWlyc3BlYy9tZXRhZGF0YVwiXG5pbXBvcnQgeyBkZXNjcmliZSwgZXhwZWN0LCBpdCB9IGZyb20gXCJ2aXRlc3RcIlxuaW1wb3J0IHsgY29udmVydFNjaGVtYVRvSHRtbCB9IGZyb20gXCIuL3RvSHRtbC50c3hcIlxuXG5kZXNjcmliZShcImNvbnZlcnRTY2hlbWFUb0h0bWxcIiwgKCkgPT4ge1xuICBpdChcImNvbnZlcnRzIGEgc2ltcGxlIHNjaGVtYSB0byBodG1sIHRhYmxlXCIsICgpID0+IHtcbiAgICBjb25zdCBzY2hlbWE6IFNjaGVtYSA9IHtcbiAgICAgIGZpZWxkczogW1xuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJpZFwiLFxuICAgICAgICAgIHR5cGU6IFwiaW50ZWdlclwiLFxuICAgICAgICAgIHRpdGxlOiBcIklkZW50aWZpZXJcIixcbiAgICAgICAgICBkZXNjcmlwdGlvbjogXCJVbmlxdWUgaWRlbnRpZmllclwiLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJuYW1lXCIsXG4gICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgICB0aXRsZTogXCJOYW1lXCIsXG4gICAgICAgICAgZGVzY3JpcHRpb246IFwiUGVyc29uIG5hbWVcIixcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gY29udmVydFNjaGVtYVRvSHRtbChzY2hlbWEpXG5cbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCI8aDI+RmllbGRzPC9oMj5cIilcbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCI8dGFibGU+XCIpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPHRoPk5hbWU8L3RoPlwiKVxuICAgIGV4cGVjdChyZXN1bHQpLnRvQ29udGFpbihcIjx0aD5EZWZpbml0aW9uPC90aD5cIilcbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCI8dGg+VHlwZTwvdGg+XCIpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPHN0cm9uZz5pZD88L3N0cm9uZz5cIilcbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCI8c3Ryb25nPm5hbWU/PC9zdHJvbmc+XCIpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPHA+VW5pcXVlIGlkZW50aWZpZXI8L3A+XCIpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPHA+UGVyc29uIG5hbWU8L3A+XCIpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPGNvZGU+aW50ZWdlcjwvY29kZT5cIilcbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCI8Y29kZT5zdHJpbmc8L2NvZGU+XCIpXG4gIH0pXG5cbiAgaXQoXCJpbmNsdWRlcyBzY2hlbWEgdGl0bGUgYW5kIGRlc2NyaXB0aW9uXCIsICgpID0+IHtcbiAgICBjb25zdCBzY2hlbWE6IFNjaGVtYSA9IHtcbiAgICAgIHRpdGxlOiBcIlRlc3QgU2NoZW1hXCIsXG4gICAgICBkZXNjcmlwdGlvbjogXCJBIHRlc3Qgc2NoZW1hIGZvciB2YWxpZGF0aW9uXCIsXG4gICAgICBmaWVsZHM6IFtcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwiZmllbGQxXCIsXG4gICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gY29udmVydFNjaGVtYVRvSHRtbChzY2hlbWEpXG5cbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oJzxoMSBpZD1cInRlc3Qtc2NoZW1hXCI+VGVzdCBTY2hlbWE8L2gxPicpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPHA+QSB0ZXN0IHNjaGVtYSBmb3IgdmFsaWRhdGlvbjwvcD5cIilcbiAgfSlcblxuICBpdChcImhhbmRsZXMgZmllbGQgY29uc3RyYWludHNcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHNjaGVtYTogU2NoZW1hID0ge1xuICAgICAgZmllbGRzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcImFnZVwiLFxuICAgICAgICAgIHR5cGU6IFwiaW50ZWdlclwiLFxuICAgICAgICAgIGNvbnN0cmFpbnRzOiB7XG4gICAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgIG1pbmltdW06IDAsXG4gICAgICAgICAgICBtYXhpbXVtOiAxMjAsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwiZW1haWxcIixcbiAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgIGNvbnN0cmFpbnRzOiB7XG4gICAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgIHBhdHRlcm46IFwiXlthLXpdK0BbYS16XStcXFxcLlthLXpdKyRcIixcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBjb252ZXJ0U2NoZW1hVG9IdG1sKHNjaGVtYSlcblxuICAgIGV4cGVjdChyZXN1bHQpLnRvQ29udGFpbihcIjxzdHJvbmc+Q29uc3RyYWludHM8L3N0cm9uZz5cIilcbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCJyZXF1aXJlZDpcIilcbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCI8Y29kZT50cnVlPC9jb2RlPlwiKVxuICAgIGV4cGVjdChyZXN1bHQpLnRvQ29udGFpbihcIm1pbmltdW06XCIpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPGNvZGU+MDwvY29kZT5cIilcbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCJtYXhpbXVtOlwiKVxuICAgIGV4cGVjdChyZXN1bHQpLnRvQ29udGFpbihcIjxjb2RlPjEyMDwvY29kZT5cIilcbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCJwYXR0ZXJuOlwiKVxuICB9KVxuXG4gIGl0KFwiaGFuZGxlcyByZXF1aXJlZCBmaWVsZCBpbmRpY2F0b3JcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHNjaGVtYTogU2NoZW1hID0ge1xuICAgICAgZmllbGRzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcInJlcXVpcmVkRmllbGRcIixcbiAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgIGNvbnN0cmFpbnRzOiB7XG4gICAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJvcHRpb25hbEZpZWxkXCIsXG4gICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gY29udmVydFNjaGVtYVRvSHRtbChzY2hlbWEpXG5cbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCI8c3Ryb25nPnJlcXVpcmVkRmllbGQ8L3N0cm9uZz5cIilcbiAgICBleHBlY3QocmVzdWx0KS5ub3QudG9Db250YWluKFwicmVxdWlyZWRGaWVsZD9cIilcbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCI8c3Ryb25nPm9wdGlvbmFsRmllbGQ/PC9zdHJvbmc+XCIpXG4gIH0pXG5cbiAgaXQoXCJoYW5kbGVzIGVtcHR5IGZpZWxkcyBhcnJheVwiLCAoKSA9PiB7XG4gICAgY29uc3Qgc2NoZW1hOiBTY2hlbWEgPSB7XG4gICAgICBmaWVsZHM6IFtdLFxuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdCA9IGNvbnZlcnRTY2hlbWFUb0h0bWwoc2NoZW1hKVxuXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPGgyPkZpZWxkczwvaDI+XCIpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPHRhYmxlPlwiKVxuICAgIGV4cGVjdChyZXN1bHQpLnRvQ29udGFpbihcIjwvdGFibGU+XCIpXG4gIH0pXG5cbiAgaXQoXCJlc2NhcGVzIEhUTUwgc3BlY2lhbCBjaGFyYWN0ZXJzXCIsICgpID0+IHtcbiAgICBjb25zdCBzY2hlbWE6IFNjaGVtYSA9IHtcbiAgICAgIHRpdGxlOiBcIlRlc3QgJiA8U2NoZW1hPlwiLFxuICAgICAgZGVzY3JpcHRpb246ICdEZXNjcmlwdGlvbiB3aXRoIFwicXVvdGVzXCIgYW5kIDx0YWdzPicsXG4gICAgICBmaWVsZHM6IFtcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwiZmllbGRcIixcbiAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkRlc2NyaXB0aW9uIHdpdGggPHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD5cIixcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gY29udmVydFNjaGVtYVRvSHRtbChzY2hlbWEpXG5cbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCJUZXN0ICZhbXA7ICZsdDtTY2hlbWEmZ3Q7XCIpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFxuICAgICAgXCJEZXNjcmlwdGlvbiB3aXRoICZxdW90O3F1b3RlcyZxdW90OyBhbmQgJmx0O3RhZ3MmZ3Q7XCIsXG4gICAgKVxuICAgIGV4cGVjdChyZXN1bHQpLnRvQ29udGFpbihcbiAgICAgIFwiRGVzY3JpcHRpb24gd2l0aCAmbHQ7c2NyaXB0Jmd0O2FsZXJ0KCYjeDI3O3hzcyYjeDI3OykmbHQ7L3NjcmlwdCZndDtcIixcbiAgICApXG4gIH0pXG5cbiAgaXQoXCJoYW5kbGVzIGZpZWxkcyB3aXRoIGVudW0gY29uc3RyYWludHNcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHNjaGVtYTogU2NoZW1hID0ge1xuICAgICAgZmllbGRzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcInN0YXR1c1wiLFxuICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgY29uc3RyYWludHM6IHtcbiAgICAgICAgICAgIGVudW06IFtcImFjdGl2ZVwiLCBcImluYWN0aXZlXCIsIFwicGVuZGluZ1wiXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBjb252ZXJ0U2NoZW1hVG9IdG1sKHNjaGVtYSlcblxuICAgIGV4cGVjdChyZXN1bHQpLnRvQ29udGFpbihcImVudW06XCIpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPGNvZGU+YWN0aXZlLCBpbmFjdGl2ZSwgcGVuZGluZzwvY29kZT5cIilcbiAgfSlcblxuICBpdChcImhhbmRsZXMgbXVsdGlwbGUgY29uc3RyYWludCB0eXBlc1wiLCAoKSA9PiB7XG4gICAgY29uc3Qgc2NoZW1hOiBTY2hlbWEgPSB7XG4gICAgICBmaWVsZHM6IFtcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwidXNlcm5hbWVcIixcbiAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgIGNvbnN0cmFpbnRzOiB7XG4gICAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgIHVuaXF1ZTogdHJ1ZSxcbiAgICAgICAgICAgIG1pbkxlbmd0aDogMyxcbiAgICAgICAgICAgIG1heExlbmd0aDogMjAsXG4gICAgICAgICAgICBwYXR0ZXJuOiBcIl5bYS16QS1aMC05X10rJFwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdCA9IGNvbnZlcnRTY2hlbWFUb0h0bWwoc2NoZW1hKVxuXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwicmVxdWlyZWQ6XCIpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwidW5pcXVlOlwiKVxuICAgIGV4cGVjdChyZXN1bHQpLnRvQ29udGFpbihcIm1pbkxlbmd0aDpcIilcbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCI8Y29kZT4zPC9jb2RlPlwiKVxuICAgIGV4cGVjdChyZXN1bHQpLnRvQ29udGFpbihcIm1heExlbmd0aDpcIilcbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCI8Y29kZT4yMDwvY29kZT5cIilcbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCJwYXR0ZXJuOlwiKVxuICB9KVxuXG4gIGl0KFwiaGFuZGxlcyBmaWVsZCBleGFtcGxlc1wiLCAoKSA9PiB7XG4gICAgY29uc3Qgc2NoZW1hOiBTY2hlbWEgPSB7XG4gICAgICBmaWVsZHM6IFtcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwiZW1haWxcIixcbiAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgIGV4YW1wbGVzOiBbXCJ1c2VyQGV4YW1wbGUuY29tXCIsIFwiYWRtaW5AdGVzdC5vcmdcIl0sXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcImFnZVwiLFxuICAgICAgICAgIHR5cGU6IFwiaW50ZWdlclwiLFxuICAgICAgICAgIGV4YW1wbGVzOiBbMjUsIDMwXSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gY29udmVydFNjaGVtYVRvSHRtbChzY2hlbWEpXG5cbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCI8c3Ryb25nPkV4YW1wbGVzPC9zdHJvbmc+XCIpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPGNvZGU+dXNlckBleGFtcGxlLmNvbTwvY29kZT5cIilcbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCI8Y29kZT5hZG1pbkB0ZXN0Lm9yZzwvY29kZT5cIilcbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCI8Y29kZT4yNTwvY29kZT5cIilcbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCI8Y29kZT4zMDwvY29kZT5cIilcbiAgfSlcblxuICBpdChcImhhbmRsZXMgZGlmZmVyZW50IGZpZWxkIHR5cGVzXCIsICgpID0+IHtcbiAgICBjb25zdCBzY2hlbWE6IFNjaGVtYSA9IHtcbiAgICAgIGZpZWxkczogW1xuICAgICAgICB7IG5hbWU6IFwiZmllbGQxXCIsIHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICAgICAgeyBuYW1lOiBcImZpZWxkMlwiLCB0eXBlOiBcImludGVnZXJcIiB9LFxuICAgICAgICB7IG5hbWU6IFwiZmllbGQzXCIsIHR5cGU6IFwibnVtYmVyXCIgfSxcbiAgICAgICAgeyBuYW1lOiBcImZpZWxkNFwiLCB0eXBlOiBcImJvb2xlYW5cIiB9LFxuICAgICAgICB7IG5hbWU6IFwiZmllbGQ1XCIsIHR5cGU6IFwiZGF0ZXRpbWVcIiB9LFxuICAgICAgICB7IG5hbWU6IFwiZmllbGQ2XCIsIHR5cGU6IFwiYW55XCIgfSxcbiAgICAgIF0sXG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gY29udmVydFNjaGVtYVRvSHRtbChzY2hlbWEpXG5cbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCI8Y29kZT5zdHJpbmc8L2NvZGU+XCIpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPGNvZGU+aW50ZWdlcjwvY29kZT5cIilcbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCI8Y29kZT5udW1iZXI8L2NvZGU+XCIpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPGNvZGU+Ym9vbGVhbjwvY29kZT5cIilcbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCI8Y29kZT5kYXRldGltZTwvY29kZT5cIilcbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCI8Y29kZT5hbnk8L2NvZGU+XCIpXG4gIH0pXG5cbiAgaXQoXCJzYW5pdGl6ZXMgSURzIGZvciBhbmNob3JzXCIsICgpID0+IHtcbiAgICBjb25zdCBzY2hlbWE6IFNjaGVtYSA9IHtcbiAgICAgIHRpdGxlOiBcIlRlc3QgU2NoZW1hICYgTW9yZSFcIixcbiAgICAgIGZpZWxkczogW1xuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJmaWVsZC13aXRoLWRhc2hlc1wiLFxuICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcIkZpZWxkIFdpdGggU3BhY2VzXCIsXG4gICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gY29udmVydFNjaGVtYVRvSHRtbChzY2hlbWEpXG5cbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oJ2lkPVwidGVzdC1zY2hlbWEtbW9yZVwiJylcbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oJ2lkPVwiZmllbGQtd2l0aC1kYXNoZXNcIicpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKCdpZD1cImZpZWxkLXdpdGgtc3BhY2VzXCInKVxuICB9KVxuXG4gIGl0KFwiZG9lcyBub3QgaW5jbHVkZSB0b3AtbGV2ZWwgaHRtbCB0YWdzXCIsICgpID0+IHtcbiAgICBjb25zdCBzY2hlbWE6IFNjaGVtYSA9IHtcbiAgICAgIHRpdGxlOiBcIlRlc3RcIixcbiAgICAgIGZpZWxkczogW3sgbmFtZTogXCJmaWVsZDFcIiwgdHlwZTogXCJzdHJpbmdcIiB9XSxcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBjb252ZXJ0U2NoZW1hVG9IdG1sKHNjaGVtYSlcblxuICAgIGV4cGVjdChyZXN1bHQpLm5vdC50b0NvbnRhaW4oXCI8IURPQ1RZUEVcIilcbiAgICBleHBlY3QocmVzdWx0KS5ub3QudG9Db250YWluKFwiPGh0bWw+XCIpXG4gICAgZXhwZWN0KHJlc3VsdCkubm90LnRvQ29udGFpbihcIjxoZWFkPlwiKVxuICAgIGV4cGVjdChyZXN1bHQpLm5vdC50b0NvbnRhaW4oXCI8Ym9keT5cIilcbiAgICBleHBlY3QocmVzdWx0KS5ub3QudG9Db250YWluKFwiPHN0eWxlPlwiKVxuICB9KVxuXG4gIGl0KFwiaGFuZGxlcyBzY2hlbWEgd2l0aG91dCB0aXRsZVwiLCAoKSA9PiB7XG4gICAgY29uc3Qgc2NoZW1hOiBTY2hlbWEgPSB7XG4gICAgICBkZXNjcmlwdGlvbjogXCJEZXNjcmlwdGlvbiBvbmx5XCIsXG4gICAgICBmaWVsZHM6IFt7IG5hbWU6IFwiZmllbGQxXCIsIHR5cGU6IFwic3RyaW5nXCIgfV0sXG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gY29udmVydFNjaGVtYVRvSHRtbChzY2hlbWEpXG5cbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCI8cD5EZXNjcmlwdGlvbiBvbmx5PC9wPlwiKVxuICAgIGV4cGVjdChyZXN1bHQpLm5vdC50b0NvbnRhaW4oXCI8aDIgaWQ9XCIpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPGgyPkZpZWxkczwvaDI+XCIpXG4gIH0pXG5cbiAgaXQoXCJoYW5kbGVzIGZpZWxkIHdpdGhvdXQgZGVzY3JpcHRpb25cIiwgKCkgPT4ge1xuICAgIGNvbnN0IHNjaGVtYTogU2NoZW1hID0ge1xuICAgICAgZmllbGRzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcImZpZWxkMVwiLFxuICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdCA9IGNvbnZlcnRTY2hlbWFUb0h0bWwoc2NoZW1hKVxuXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPHN0cm9uZz5maWVsZDE/PC9zdHJvbmc+XCIpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPGNvZGU+c3RyaW5nPC9jb2RlPlwiKVxuICB9KVxuXG4gIGl0KFwidXNlcyBmcm9udG1hdHRlciB3aGVuIGZyb250bWF0dGVyIG9wdGlvbiBpcyB0cnVlXCIsICgpID0+IHtcbiAgICBjb25zdCBzY2hlbWE6IFNjaGVtYSA9IHtcbiAgICAgIHRpdGxlOiBcIlRlc3QgU2NoZW1hXCIsXG4gICAgICBkZXNjcmlwdGlvbjogXCJBIHRlc3Qgc2NoZW1hIHdpdGggZnJvbnRtYXR0ZXJcIixcbiAgICAgIGZpZWxkczogW1xuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJmaWVsZDFcIixcbiAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBjb252ZXJ0U2NoZW1hVG9IdG1sKHNjaGVtYSwgeyBmcm9udG1hdHRlcjogdHJ1ZSB9KVxuXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiLS0tXCIpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiVGVzdCBTY2hlbWFcIilcbiAgICBleHBlY3QocmVzdWx0KS5ub3QudG9Db250YWluKFwiPGgxXCIpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPHA+QSB0ZXN0IHNjaGVtYSB3aXRoIGZyb250bWF0dGVyPC9wPlwiKVxuICB9KVxuXG4gIGl0KFwidXNlcyBIMSBoZWFkaW5nIHdoZW4gZnJvbnRtYXR0ZXIgb3B0aW9uIGlzIGZhbHNlIG9yIG5vdCBwcm92aWRlZFwiLCAoKSA9PiB7XG4gICAgY29uc3Qgc2NoZW1hOiBTY2hlbWEgPSB7XG4gICAgICB0aXRsZTogXCJUZXN0IFNjaGVtYVwiLFxuICAgICAgZmllbGRzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcImZpZWxkMVwiLFxuICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdCA9IGNvbnZlcnRTY2hlbWFUb0h0bWwoc2NoZW1hLCB7IGZyb250bWF0dGVyOiBmYWxzZSB9KVxuXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKCc8aDEgaWQ9XCJ0ZXN0LXNjaGVtYVwiPlRlc3QgU2NoZW1hPC9oMT4nKVxuICAgIGV4cGVjdChyZXN1bHQpLm5vdC50b0NvbnRhaW4oXCJ0aXRsZTogVGVzdCBTY2hlbWFcIilcbiAgICBleHBlY3QocmVzdWx0LnN0YXJ0c1dpdGgoXCI8aDFcIikpLnRvQmUodHJ1ZSlcbiAgfSlcblxuICBpdChcImhhbmRsZXMgc2NoZW1hIHdpdGggcHJpbWFyeSBrZXlcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHNjaGVtYTogU2NoZW1hID0ge1xuICAgICAgZmllbGRzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcImlkXCIsXG4gICAgICAgICAgdHlwZTogXCJpbnRlZ2VyXCIsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcIm5hbWVcIixcbiAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIHByaW1hcnlLZXk6IFtcImlkXCJdLFxuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdCA9IGNvbnZlcnRTY2hlbWFUb0h0bWwoc2NoZW1hKVxuXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPGgyPlByaW1hcnkgS2V5PC9oMj5cIilcbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCI8Y29kZT5pZDwvY29kZT5cIilcbiAgfSlcblxuICBpdChcImhhbmRsZXMgc2NoZW1hIHdpdGggY29tcG9zaXRlIHByaW1hcnkga2V5XCIsICgpID0+IHtcbiAgICBjb25zdCBzY2hlbWE6IFNjaGVtYSA9IHtcbiAgICAgIGZpZWxkczogW1xuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJ1c2VyX2lkXCIsXG4gICAgICAgICAgdHlwZTogXCJpbnRlZ2VyXCIsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcInByb2plY3RfaWRcIixcbiAgICAgICAgICB0eXBlOiBcImludGVnZXJcIixcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgICBwcmltYXJ5S2V5OiBbXCJ1c2VyX2lkXCIsIFwicHJvamVjdF9pZFwiXSxcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBjb252ZXJ0U2NoZW1hVG9IdG1sKHNjaGVtYSlcblxuICAgIGV4cGVjdChyZXN1bHQpLnRvQ29udGFpbihcIjxoMj5QcmltYXJ5IEtleTwvaDI+XCIpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPGNvZGU+dXNlcl9pZCwgcHJvamVjdF9pZDwvY29kZT5cIilcbiAgfSlcblxuICBpdChcImhhbmRsZXMgc2NoZW1hIHdpdGggZm9yZWlnbiBrZXlzXCIsICgpID0+IHtcbiAgICBjb25zdCBzY2hlbWE6IFNjaGVtYSA9IHtcbiAgICAgIGZpZWxkczogW1xuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJ1c2VyX2lkXCIsXG4gICAgICAgICAgdHlwZTogXCJpbnRlZ2VyXCIsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAgZm9yZWlnbktleXM6IFtcbiAgICAgICAge1xuICAgICAgICAgIGZpZWxkczogW1widXNlcl9pZFwiXSxcbiAgICAgICAgICByZWZlcmVuY2U6IHtcbiAgICAgICAgICAgIHJlc291cmNlOiBcInVzZXJzXCIsXG4gICAgICAgICAgICBmaWVsZHM6IFtcImlkXCJdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdCA9IGNvbnZlcnRTY2hlbWFUb0h0bWwoc2NoZW1hKVxuXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPGgyPkZvcmVpZ24gS2V5czwvaDI+XCIpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPHRoPkZpZWxkczwvdGg+XCIpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPHRoPlJlZmVyZW5jZSBSZXNvdXJjZTwvdGg+XCIpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPHRoPlJlZmVyZW5jZSBGaWVsZHM8L3RoPlwiKVxuICAgIGV4cGVjdChyZXN1bHQpLnRvQ29udGFpbihcIjxjb2RlPnVzZXJfaWQ8L2NvZGU+XCIpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPGNvZGU+dXNlcnM8L2NvZGU+XCIpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPGNvZGU+aWQ8L2NvZGU+XCIpXG4gIH0pXG5cbiAgaXQoXCJoYW5kbGVzIHNjaGVtYSB3aXRoIG11bHRpcGxlIGZvcmVpZ24ga2V5c1wiLCAoKSA9PiB7XG4gICAgY29uc3Qgc2NoZW1hOiBTY2hlbWEgPSB7XG4gICAgICBmaWVsZHM6IFtcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwidXNlcl9pZFwiLFxuICAgICAgICAgIHR5cGU6IFwiaW50ZWdlclwiLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJwcm9qZWN0X2lkXCIsXG4gICAgICAgICAgdHlwZTogXCJpbnRlZ2VyXCIsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAgZm9yZWlnbktleXM6IFtcbiAgICAgICAge1xuICAgICAgICAgIGZpZWxkczogW1widXNlcl9pZFwiXSxcbiAgICAgICAgICByZWZlcmVuY2U6IHtcbiAgICAgICAgICAgIHJlc291cmNlOiBcInVzZXJzXCIsXG4gICAgICAgICAgICBmaWVsZHM6IFtcImlkXCJdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBmaWVsZHM6IFtcInByb2plY3RfaWRcIl0sXG4gICAgICAgICAgcmVmZXJlbmNlOiB7XG4gICAgICAgICAgICByZXNvdXJjZTogXCJwcm9qZWN0c1wiLFxuICAgICAgICAgICAgZmllbGRzOiBbXCJpZFwiXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBjb252ZXJ0U2NoZW1hVG9IdG1sKHNjaGVtYSlcblxuICAgIGV4cGVjdChyZXN1bHQpLnRvQ29udGFpbihcIjxoMj5Gb3JlaWduIEtleXM8L2gyPlwiKVxuICAgIGV4cGVjdChyZXN1bHQpLnRvQ29udGFpbihcIjxjb2RlPnVzZXJfaWQ8L2NvZGU+XCIpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPGNvZGU+dXNlcnM8L2NvZGU+XCIpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPGNvZGU+cHJvamVjdF9pZDwvY29kZT5cIilcbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCI8Y29kZT5wcm9qZWN0czwvY29kZT5cIilcbiAgfSlcblxuICBpdChcImhhbmRsZXMgZm9yZWlnbiBrZXkgd2l0aG91dCByZXNvdXJjZSBzcGVjaWZpZWRcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHNjaGVtYTogU2NoZW1hID0ge1xuICAgICAgZmllbGRzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcInBhcmVudF9pZFwiLFxuICAgICAgICAgIHR5cGU6IFwiaW50ZWdlclwiLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIGZvcmVpZ25LZXlzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBmaWVsZHM6IFtcInBhcmVudF9pZFwiXSxcbiAgICAgICAgICByZWZlcmVuY2U6IHtcbiAgICAgICAgICAgIGZpZWxkczogW1wiaWRcIl0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gY29udmVydFNjaGVtYVRvSHRtbChzY2hlbWEpXG5cbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCI8aDI+Rm9yZWlnbiBLZXlzPC9oMj5cIilcbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCI8Y29kZT5wYXJlbnRfaWQ8L2NvZGU+XCIpXG4gICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKFwiPGNvZGU+LTwvY29kZT5cIilcbiAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oXCI8Y29kZT5pZDwvY29kZT5cIilcbiAgfSlcblxuICBpdChcImRvZXMgbm90IHJlbmRlciBwcmltYXJ5IGtleSBvciBmb3JlaWduIGtleXMgc2VjdGlvbnMgd2hlbiBub3QgcHJlc2VudFwiLCAoKSA9PiB7XG4gICAgY29uc3Qgc2NoZW1hOiBTY2hlbWEgPSB7XG4gICAgICBmaWVsZHM6IFtcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwiZmllbGQxXCIsXG4gICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gY29udmVydFNjaGVtYVRvSHRtbChzY2hlbWEpXG5cbiAgICBleHBlY3QocmVzdWx0KS5ub3QudG9Db250YWluKFwiPGgyPlByaW1hcnkgS2V5PC9oMj5cIilcbiAgICBleHBlY3QocmVzdWx0KS5ub3QudG9Db250YWluKFwiPGgyPkZvcmVpZ24gS2V5czwvaDI+XCIpXG4gIH0pXG59KVxuIl19
@@ -0,0 +1,4 @@
1
+ import type { Schema } from "@fairspec/metadata";
2
+ export declare function convertSchemaToMarkdown(schema: Schema, options?: {
3
+ frontmatter?: boolean;
4
+ }): string;
@@ -0,0 +1,75 @@
1
+ export function convertSchemaToMarkdown(schema, options) {
2
+ const rows = [];
3
+ rows.push("");
4
+ rows.push("## Fields");
5
+ rows.push("");
6
+ rows.push("| Name | Type | Title | Description | Constraints |");
7
+ rows.push("|------|------|-------|-------------|-------------|");
8
+ for (const field of schema.fields) {
9
+ const name = field.name || "";
10
+ const type = field.type || "any";
11
+ const title = field.title || "";
12
+ const description = field.description || "";
13
+ const constraints = [];
14
+ if ("required" in field && field.required) {
15
+ constraints.push("required");
16
+ }
17
+ if ("constraints" in field && field.constraints) {
18
+ const c = field.constraints;
19
+ if (c.required)
20
+ constraints.push("required");
21
+ if (c.unique)
22
+ constraints.push("unique");
23
+ if (c.minimum !== undefined)
24
+ constraints.push(`min: ${c.minimum}`);
25
+ if (c.maximum !== undefined)
26
+ constraints.push(`max: ${c.maximum}`);
27
+ if (c.minLength !== undefined)
28
+ constraints.push(`minLength: ${c.minLength}`);
29
+ if (c.maxLength !== undefined)
30
+ constraints.push(`maxLength: ${c.maxLength}`);
31
+ if (c.pattern)
32
+ constraints.push(`pattern: ${c.pattern}`);
33
+ if (c.enum)
34
+ constraints.push(`enum: ${c.enum.join(", ")}`);
35
+ }
36
+ const constraintsStr = constraints.join(", ");
37
+ const escapedName = escapeMarkdown(name);
38
+ const escapedTitle = escapeMarkdown(title);
39
+ const escapedDescription = escapeMarkdown(description);
40
+ const escapedConstraints = escapeMarkdown(constraintsStr);
41
+ rows.push(`| ${escapedName} | ${type} | ${escapedTitle} | ${escapedDescription} | ${escapedConstraints} |`);
42
+ }
43
+ let markdown = `${rows.join("\n")}\n`;
44
+ if (schema.title || schema.description) {
45
+ const header = [];
46
+ if (options?.frontmatter) {
47
+ header.push("---");
48
+ if (schema.title) {
49
+ header.push(`title: ${schema.title}`);
50
+ }
51
+ header.push("---");
52
+ header.push("");
53
+ if (schema.description) {
54
+ header.push(schema.description);
55
+ header.push("");
56
+ }
57
+ }
58
+ else {
59
+ if (schema.title) {
60
+ header.push(`# ${schema.title}`);
61
+ header.push("");
62
+ }
63
+ if (schema.description) {
64
+ header.push(schema.description);
65
+ header.push("");
66
+ }
67
+ }
68
+ markdown = header.join("\n") + markdown;
69
+ }
70
+ return markdown;
71
+ }
72
+ function escapeMarkdown(text) {
73
+ return text.replace(/\n/g, " ");
74
+ }
75
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9NYXJrZG93bi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NjaGVtYS9jb252ZXJ0L3RvTWFya2Rvd24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsTUFBTSxVQUFVLHVCQUF1QixDQUNyQyxNQUFjLEVBQ2QsT0FBbUM7SUFFbkMsTUFBTSxJQUFJLEdBQWEsRUFBRSxDQUFBO0lBRXpCLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7SUFDYixJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFBO0lBQ3RCLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7SUFDYixJQUFJLENBQUMsSUFBSSxDQUFDLHFEQUFxRCxDQUFDLENBQUE7SUFDaEUsSUFBSSxDQUFDLElBQUksQ0FBQyxxREFBcUQsQ0FBQyxDQUFBO0lBRWhFLEtBQUssTUFBTSxLQUFLLElBQUksTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2xDLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFBO1FBQzdCLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxJQUFJLElBQUksS0FBSyxDQUFBO1FBQ2hDLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFBO1FBQy9CLE1BQU0sV0FBVyxHQUFHLEtBQUssQ0FBQyxXQUFXLElBQUksRUFBRSxDQUFBO1FBRTNDLE1BQU0sV0FBVyxHQUFhLEVBQUUsQ0FBQTtRQUNoQyxJQUFJLFVBQVUsSUFBSSxLQUFLLElBQUksS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQzFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUE7UUFDOUIsQ0FBQztRQUNELElBQUksYUFBYSxJQUFJLEtBQUssSUFBSSxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDaEQsTUFBTSxDQUFDLEdBQUcsS0FBSyxDQUFDLFdBQWtCLENBQUE7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O1lBQ2pCLENBQUM7WUFFRCxJQUFJLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQkFDdkIsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUE7Z0JBQy9CLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7WUFDakIsQ0FBQztRQUNILENBQUM7UUFFRCxRQUFRLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxRQUFRLENBQUE7SUFDekMsQ0FBQztJQUVELE9BQU8sUUFBUSxDQUFBO0FBQ2pCLENBQUM7QUFFRCxTQUFTLGNBQWMsQ0FBQyxJQUFZO0lBQ2xDLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUE7QUFDakMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgU2NoZW1hIH0gZnJvbSBcIkBmYWlyc3BlYy9tZXRhZGF0YVwiXG5cbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0U2NoZW1hVG9NYXJrZG93bihcbiAgc2NoZW1hOiBTY2hlbWEsXG4gIG9wdGlvbnM/OiB7IGZyb250bWF0dGVyPzogYm9vbGVhbiB9LFxuKTogc3RyaW5nIHtcbiAgY29uc3Qgcm93czogc3RyaW5nW10gPSBbXVxuXG4gIHJvd3MucHVzaChcIlwiKVxuICByb3dzLnB1c2goXCIjIyBGaWVsZHNcIilcbiAgcm93cy5wdXNoKFwiXCIpXG4gIHJvd3MucHVzaChcInwgTmFtZSB8IFR5cGUgfCBUaXRsZSB8IERlc2NyaXB0aW9uIHwgQ29uc3RyYWludHMgfFwiKVxuICByb3dzLnB1c2goXCJ8LS0tLS0tfC0tLS0tLXwtLS0tLS0tfC0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLXxcIilcblxuICBmb3IgKGNvbnN0IGZpZWxkIG9mIHNjaGVtYS5maWVsZHMpIHtcbiAgICBjb25zdCBuYW1lID0gZmllbGQubmFtZSB8fCBcIlwiXG4gICAgY29uc3QgdHlwZSA9IGZpZWxkLnR5cGUgfHwgXCJhbnlcIlxuICAgIGNvbnN0IHRpdGxlID0gZmllbGQudGl0bGUgfHwgXCJcIlxuICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gZmllbGQuZGVzY3JpcHRpb24gfHwgXCJcIlxuXG4gICAgY29uc3QgY29uc3RyYWludHM6IHN0cmluZ1tdID0gW11cbiAgICBpZiAoXCJyZXF1aXJlZFwiIGluIGZpZWxkICYmIGZpZWxkLnJlcXVpcmVkKSB7XG4gICAgICBjb25zdHJhaW50cy5wdXNoKFwicmVxdWlyZWRcIilcbiAgICB9XG4gICAgaWYgKFwiY29uc3RyYWludHNcIiBpbiBmaWVsZCAmJiBmaWVsZC5jb25zdHJhaW50cykge1xuICAgICAgY29uc3QgYyA9IGZpZWxkLmNvbnN0cmFpbnRzIGFzIGFueVxuICAgICAgaWYgKGMucmVxdWlyZWQpIGNvbnN0cmFpbnRzLnB1c2goXCJyZXF1aXJlZFwiKVxuICAgICAgaWYgKGMudW5pcXVlKSBjb25zdHJhaW50cy5wdXNoKFwidW5pcXVlXCIpXG4gICAgICBpZiAoYy5taW5pbXVtICE9PSB1bmRlZmluZWQpIGNvbnN0cmFpbnRzLnB1c2goYG1pbjogJHtjLm1pbmltdW19YClcbiAgICAgIGlmIChjLm1heGltdW0gIT09IHVuZGVmaW5lZCkgY29uc3RyYWludHMucHVzaChgbWF4OiAke2MubWF4aW11bX1gKVxuICAgICAgaWYgKGMubWluTGVuZ3RoICE9PSB1bmRlZmluZWQpXG4gICAgICAgIGNvbnN0cmFpbnRzLnB1c2goYG1pbkxlbmd0aDogJHtjLm1pbkxlbmd0aH1gKVxuICAgICAgaWYgKGMubWF4TGVuZ3RoICE9PSB1bmRlZmluZWQpXG4gICAgICAgIGNvbnN0cmFpbnRzLnB1c2goYG1heExlbmd0aDogJHtjLm1heExlbmd0aH1gKVxuICAgICAgaWYgKGMucGF0dGVybikgY29uc3RyYWludHMucHVzaChgcGF0dGVybjogJHtjLnBhdHRlcm59YClcbiAgICAgIGlmIChjLmVudW0pIGNvbnN0cmFpbnRzLnB1c2goYGVudW06ICR7Yy5lbnVtLmpvaW4oXCIsIFwiKX1gKVxuICAgIH1cblxuICAgIGNvbnN0IGNvbnN0cmFpbnRzU3RyID0gY29uc3RyYWludHMuam9pbihcIiwgXCIpXG5cbiAgICBjb25zdCBlc2NhcGVkTmFtZSA9IGVzY2FwZU1hcmtkb3duKG5hbWUpXG4gICAgY29uc3QgZXNjYXBlZFRpdGxlID0gZXNjYXBlTWFya2Rvd24odGl0bGUpXG4gICAgY29uc3QgZXNjYXBlZERlc2NyaXB0aW9uID0gZXNjYXBlTWFya2Rvd24oZGVzY3JpcHRpb24pXG4gICAgY29uc3QgZXNjYXBlZENvbnN0cmFpbnRzID0gZXNjYXBlTWFya2Rvd24oY29uc3RyYWludHNTdHIpXG5cbiAgICByb3dzLnB1c2goXG4gICAgICBgfCAke2VzY2FwZWROYW1lfSB8ICR7dHlwZX0gfCAke2VzY2FwZWRUaXRsZX0gfCAke2VzY2FwZWREZXNjcmlwdGlvbn0gfCAke2VzY2FwZWRDb25zdHJhaW50c30gfGAsXG4gICAgKVxuICB9XG5cbiAgbGV0IG1hcmtkb3duID0gYCR7cm93cy5qb2luKFwiXFxuXCIpfVxcbmBcblxuICBpZiAoc2NoZW1hLnRpdGxlIHx8IHNjaGVtYS5kZXNjcmlwdGlvbikge1xuICAgIGNvbnN0IGhlYWRlcjogc3RyaW5nW10gPSBbXVxuXG4gICAgaWYgKG9wdGlvbnM/LmZyb250bWF0dGVyKSB7XG4gICAgICBoZWFkZXIucHVzaChcIi0tLVwiKVxuICAgICAgaWYgKHNjaGVtYS50aXRsZSkge1xuICAgICAgICBoZWFkZXIucHVzaChgdGl0bGU6ICR7c2NoZW1hLnRpdGxlfWApXG4gICAgICB9XG4gICAgICBoZWFkZXIucHVzaChcIi0tLVwiKVxuICAgICAgaGVhZGVyLnB1c2goXCJcIilcblxuICAgICAgaWYgKHNjaGVtYS5kZXNjcmlwdGlvbikge1xuICAgICAgICBoZWFkZXIucHVzaChzY2hlbWEuZGVzY3JpcHRpb24pXG4gICAgICAgIGhlYWRlci5wdXNoKFwiXCIpXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChzY2hlbWEudGl0bGUpIHtcbiAgICAgICAgaGVhZGVyLnB1c2goYCMgJHtzY2hlbWEudGl0bGV9YClcbiAgICAgICAgaGVhZGVyLnB1c2goXCJcIilcbiAgICAgIH1cblxuICAgICAgaWYgKHNjaGVtYS5kZXNjcmlwdGlvbikge1xuICAgICAgICBoZWFkZXIucHVzaChzY2hlbWEuZGVzY3JpcHRpb24pXG4gICAgICAgIGhlYWRlci5wdXNoKFwiXCIpXG4gICAgICB9XG4gICAgfVxuXG4gICAgbWFya2Rvd24gPSBoZWFkZXIuam9pbihcIlxcblwiKSArIG1hcmtkb3duXG4gIH1cblxuICByZXR1cm4gbWFya2Rvd25cbn1cblxuZnVuY3Rpb24gZXNjYXBlTWFya2Rvd24odGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHRleHQucmVwbGFjZSgvXFxuL2csIFwiIFwiKVxufVxuIl19
@@ -0,0 +1 @@
1
+ export {};