@dpkit/table
Version:
Data Package implementation in TypeScript.
260 lines • 35.5 kB
JavaScript
import { DataFrame, Series } from "nodejs-polars";
import { DataType } from "nodejs-polars";
import { describe, expect, it } from "vitest";
import { inferSchemaFromTable } from "./infer.js";
describe("inferSchemaFromTable", () => {
it("should infer from native types", async () => {
const table = DataFrame({
integer: Series("integer", [1, 2], DataType.Int32),
number: [1.1, 2.2],
}).lazy();
const schema = {
fields: [
{ name: "integer", type: "integer" },
{ name: "number", type: "number" },
],
};
expect(await inferSchemaFromTable(table)).toEqual(schema);
});
it("should infer numeric", async () => {
const table = DataFrame({
name1: ["1", "2", "3"],
name2: ["1,000", "2,000", "3,000"],
name3: ["1.1", "2.2", "3.3"],
name4: ["1,000.1", "2,000.2", "3,000.3"],
}).lazy();
const schema = {
fields: [
{ name: "name1", type: "integer" },
{ name: "name2", type: "integer", groupChar: "," },
{ name: "name3", type: "number" },
{ name: "name4", type: "number", groupChar: "," },
],
};
expect(await inferSchemaFromTable(table)).toEqual(schema);
});
it("should infer numeric (commaDecimal)", async () => {
const table = DataFrame({
name1: ["1.000", "2.000", "3.000"],
name2: ["1.000,5", "2.000,5", "3.000,5"],
}).lazy();
const schema = {
fields: [
{ name: "name1", type: "integer", groupChar: "." },
{ name: "name2", type: "number", decimalChar: ",", groupChar: "." },
],
};
expect(await inferSchemaFromTable(table, { commaDecimal: true })).toEqual(schema);
});
it("should infer booleans", async () => {
const table = DataFrame({
name1: ["true", "True", "TRUE"],
name2: ["false", "False", "FALSE"],
}).lazy();
const schema = {
fields: [
{ name: "name1", type: "boolean" },
{ name: "name2", type: "boolean" },
],
};
expect(await inferSchemaFromTable(table)).toEqual(schema);
});
it("should infer objects", async () => {
const table = DataFrame({
name1: ['{"a": 1}'],
name2: ["{}"],
}).lazy();
const schema = {
fields: [
{ name: "name1", type: "object" },
{ name: "name2", type: "object" },
],
};
expect(await inferSchemaFromTable(table)).toEqual(schema);
});
it("should infer arrays", async () => {
const table = DataFrame({
name1: ["[1,2,3]"],
name2: ["[]"],
}).lazy();
const schema = {
fields: [
{ name: "name1", type: "array" },
{ name: "name2", type: "array" },
],
};
expect(await inferSchemaFromTable(table)).toEqual(schema);
});
it("should infer dates with ISO format", async () => {
const table = DataFrame({
name1: ["2023-01-15", "2023-02-20", "2023-03-25"],
}).lazy();
const schema = {
fields: [{ name: "name1", type: "date" }],
};
expect(await inferSchemaFromTable(table)).toEqual(schema);
});
it("should infer dates with slash format", async () => {
const table = DataFrame({
yearFirst: ["2023/01/15", "2023/02/20", "2023/03/25"],
dayMonth: ["15/01/2023", "20/02/2023", "25/03/2023"],
monthDay: ["01/15/2023", "02/20/2023", "03/25/2023"],
}).lazy();
const schemaDefault = {
fields: [
{ name: "yearFirst", type: "date", format: "%Y/%m/%d" },
{ name: "dayMonth", type: "date", format: "%d/%m/%Y" },
{ name: "monthDay", type: "date", format: "%d/%m/%Y" },
],
};
const schemaMonthFirst = {
fields: [
{ name: "yearFirst", type: "date", format: "%Y/%m/%d" },
{ name: "dayMonth", type: "date", format: "%m/%d/%Y" },
{ name: "monthDay", type: "date", format: "%m/%d/%Y" },
],
};
expect(await inferSchemaFromTable(table)).toEqual(schemaDefault);
expect(await inferSchemaFromTable(table, { monthFirst: true })).toEqual(schemaMonthFirst);
});
it("should infer dates with hyphen format", async () => {
const table = DataFrame({
dayMonth: ["15-01-2023", "20-02-2023", "25-03-2023"],
}).lazy();
const schemaDefault = {
fields: [{ name: "dayMonth", type: "date", format: "%d-%m-%Y" }],
};
const schemaMonthFirst = {
fields: [{ name: "dayMonth", type: "date", format: "%m-%d-%Y" }],
};
expect(await inferSchemaFromTable(table)).toEqual(schemaDefault);
expect(await inferSchemaFromTable(table, { monthFirst: true })).toEqual(schemaMonthFirst);
});
it("should infer times with standard format", async () => {
const table = DataFrame({
fullTime: ["14:30:45", "08:15:30", "23:59:59"],
shortTime: ["14:30", "08:15", "23:59"],
}).lazy();
const schema = {
fields: [
{ name: "fullTime", type: "time" },
{ name: "shortTime", type: "time", format: "%H:%M" },
],
};
expect(await inferSchemaFromTable(table)).toEqual(schema);
});
it("should infer times with 12-hour format", async () => {
const table = DataFrame({
fullTime: ["2:30:45 PM", "8:15:30 AM", "11:59:59 PM"],
shortTime: ["2:30 PM", "8:15 AM", "11:59 PM"],
}).lazy();
const schema = {
fields: [
{ name: "fullTime", type: "time", format: "%I:%M:%S %p" },
{ name: "shortTime", type: "time", format: "%I:%M %p" },
],
};
expect(await inferSchemaFromTable(table)).toEqual(schema);
});
it("should infer times with timezone offset", async () => {
const table = DataFrame({
name: ["14:30:45+01:00", "08:15:30-05:00", "23:59:59+00:00"],
}).lazy();
const schema = {
fields: [{ name: "name", type: "time" }],
};
expect(await inferSchemaFromTable(table)).toEqual(schema);
});
it("should infer datetimes with ISO format", async () => {
const table = DataFrame({
standard: [
"2023-01-15T14:30:45",
"2023-02-20T08:15:30",
"2023-03-25T23:59:59",
],
utc: [
"2023-01-15T14:30:45Z",
"2023-02-20T08:15:30Z",
"2023-03-25T23:59:59Z",
],
withTz: [
"2023-01-15T14:30:45+01:00",
"2023-02-20T08:15:30-05:00",
"2023-03-25T23:59:59+00:00",
],
withSpace: [
"2023-01-15 14:30:45",
"2023-02-20 08:15:30",
"2023-03-25 23:59:59",
],
}).lazy();
const schema = {
fields: [
{ name: "standard", type: "datetime" },
{ name: "utc", type: "datetime" },
{ name: "withTz", type: "datetime" },
{ name: "withSpace", type: "datetime", format: "%Y-%m-%d %H:%M:%S" },
],
};
expect(await inferSchemaFromTable(table)).toEqual(schema);
});
it("should infer datetimes with custom formats", async () => {
const table = DataFrame({
shortDayMonth: [
"15/01/2023 14:30",
"20/02/2023 08:15",
"25/03/2023 23:59",
],
fullDayMonth: [
"15/01/2023 14:30:45",
"20/02/2023 08:15:30",
"25/03/2023 23:59:59",
],
shortMonthDay: [
"01/15/2023 14:30",
"02/20/2023 08:15",
"03/25/2023 23:59",
],
fullMonthDay: [
"01/15/2023 14:30:45",
"02/20/2023 08:15:30",
"03/25/2023 23:59:59",
],
}).lazy();
const schemaDefault = {
fields: [
{ name: "shortDayMonth", type: "datetime", format: "%d/%m/%Y %H:%M" },
{ name: "fullDayMonth", type: "datetime", format: "%d/%m/%Y %H:%M:%S" },
{ name: "shortMonthDay", type: "datetime", format: "%d/%m/%Y %H:%M" },
{ name: "fullMonthDay", type: "datetime", format: "%d/%m/%Y %H:%M:%S" },
],
};
const schemaMonthFirst = {
fields: [
{ name: "shortDayMonth", type: "datetime", format: "%m/%d/%Y %H:%M" },
{ name: "fullDayMonth", type: "datetime", format: "%m/%d/%Y %H:%M:%S" },
{ name: "shortMonthDay", type: "datetime", format: "%m/%d/%Y %H:%M" },
{ name: "fullMonthDay", type: "datetime", format: "%m/%d/%Y %H:%M:%S" },
],
};
expect(await inferSchemaFromTable(table)).toEqual(schemaDefault);
expect(await inferSchemaFromTable(table, { monthFirst: true })).toEqual(schemaMonthFirst);
});
it("should infer lists", async () => {
const table = DataFrame({
numericList: ["1.5,2.3", "4.1,5.9", "7.2,8.6"],
integerList: ["1,2", "3,4", "5,6"],
singleValue: ["1.5", "2.3", "4.1"],
}).lazy();
const schema = {
fields: [
{ name: "numericList", type: "list", itemType: "number" },
{ name: "integerList", type: "list", itemType: "integer" },
{ name: "singleValue", type: "number" },
],
missingValues: undefined,
};
expect(await inferSchemaFromTable(table)).toEqual(schema);
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5mZXIuc3BlYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NjaGVtYS9pbmZlci5zcGVjLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFBO0FBQ2pELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUE7QUFDeEMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLE1BQU0sUUFBUSxDQUFBO0FBQzdDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUVqRCxRQUFRLENBQUMsc0JBQXNCLEVBQUUsR0FBRyxFQUFFO0lBQ3BDLEVBQUUsQ0FBQyxnQ0FBZ0MsRUFBRSxLQUFLLElBQUksRUFBRTtRQUM5QyxNQUFNLEtBQUssR0FBRyxTQUFTLENBQUM7WUFDdEIsT0FBTyxFQUFFLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQztZQUNsRCxNQUFNLEVBQUUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDO1NBQ25CLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQTtRQUVULE1BQU0sTUFBTSxHQUFHO1lBQ2IsTUFBTSxFQUFFO2dCQUNOLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFO2dCQUNwQyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRTthQUNuQztTQUNGLENBQUE7UUFFRCxNQUFNLENBQUMsTUFBTSxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUMzRCxDQUFDLENBQUMsQ0FBQTtJQUVGLEVBQUUsQ0FBQyxzQkFBc0IsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNwQyxNQUFNLEtBQUssR0FBRyxTQUFT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QUFNLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRTtnQkFDekQsRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRTtnQkFDMUQsRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUU7YUFDeEM7WUFDRCxhQUFhLEVBQUUsU0FBUztTQUN6QixDQUFBO1FBRUQsTUFBTSxDQUFDLE1BQU0sb0JBQW9CLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUE7SUFDM0QsQ0FBQyxDQUFDLENBQUE7QUFDSixDQUFDLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERhdGFGcmFtZSwgU2VyaWVzIH0gZnJvbSBcIm5vZGVqcy1wb2xhcnNcIlxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tIFwibm9kZWpzLXBvbGFyc1wiXG5pbXBvcnQgeyBkZXNjcmliZSwgZXhwZWN0LCBpdCB9IGZyb20gXCJ2aXRlc3RcIlxuaW1wb3J0IHsgaW5mZXJTY2hlbWFGcm9tVGFibGUgfSBmcm9tIFwiLi9pbmZlci50c1wiXG5cbmRlc2NyaWJlKFwiaW5mZXJTY2hlbWFGcm9tVGFibGVcIiwgKCkgPT4ge1xuICBpdChcInNob3VsZCBpbmZlciBmcm9tIG5hdGl2ZSB0eXBlc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdGFibGUgPSBEYXRhRnJhbWUoe1xuICAgICAgaW50ZWdlcjogU2VyaWVzKFwiaW50ZWdlclwiLCBbMSwgMl0sIERhdGFUeXBlLkludDMyKSxcbiAgICAgIG51bWJlcjogWzEuMSwgMi4yXSxcbiAgICB9KS5sYXp5KClcblxuICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgIGZpZWxkczogW1xuICAgICAgICB7IG5hbWU6IFwiaW50ZWdlclwiLCB0eXBlOiBcImludGVnZXJcIiB9LFxuICAgICAgICB7IG5hbWU6IFwibnVtYmVyXCIsIHR5cGU6IFwibnVtYmVyXCIgfSxcbiAgICAgIF0sXG4gICAgfVxuXG4gICAgZXhwZWN0KGF3YWl0IGluZmVyU2NoZW1hRnJvbVRhYmxlKHRhYmxlKSkudG9FcXVhbChzY2hlbWEpXG4gIH0pXG5cbiAgaXQoXCJzaG91bGQgaW5mZXIgbnVtZXJpY1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdGFibGUgPSBEYXRhRnJhbWUoe1xuICAgICAgbmFtZTE6IFtcIjFcIiwgXCIyXCIsIFwiM1wiXSxcbiAgICAgIG5hbWUyOiBbXCIxLDAwMFwiLCBcIjIsMDAwXCIsIFwiMywwMDBcIl0sXG4gICAgICBuYW1lMzogW1wiMS4xXCIsIFwiMi4yXCIsIFwiMy4zXCJdLFxuICAgICAgbmFtZTQ6IFtcIjEsMDAwLjFcIiwgXCIyLDAwMC4yXCIsIFwiMywwMDAuM1wiXSxcbiAgICB9KS5sYXp5KClcblxuICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgIGZpZWxkczogW1xuICAgICAgICB7IG5hbWU6IFwibmFtZTFcIiwgdHlwZTogXCJpbnRlZ2VyXCIgfSxcbiAgICAgICAgeyBuYW1lOiBcIm5hbWUyXCIsIHR5cGU6IFwiaW50ZWdlclwiLCBncm91cENoYXI6IFwiLFwiIH0sXG4gICAgICAgIHsgbmFtZTogXCJuYW1lM1wiLCB0eXBlOiBcIm51bWJlclwiIH0sXG4gICAgICAgIHsgbmFtZTogXCJuYW1lNFwiLCB0eXBlOiBcIm51bWJlclwiLCBncm91cENoYXI6IFwiLFwiIH0sXG4gICAgICBdLFxuICAgIH1cblxuICAgIGV4cGVjdChhd2FpdCBpbmZlclNjaGVtYUZyb21UYWJsZSh0YWJsZSkpLnRvRXF1YWwoc2NoZW1hKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIGluZmVyIG51bWVyaWMgKGNvbW1hRGVjaW1hbClcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHRhYmxlID0gRGF0YUZyYW1lKHtcbiAgICAgIG5hbWUxOiBbXCIxLjAwMFwiLCBcIjIuMDAwXCIsIFwiMy4wMDBcIl0sXG4gICAgICBuYW1lMjogW1wiMS4wMDAsNVwiLCBcIjIuMDAwLDVcIiwgXCIzLjAwMCw1XCJdLFxuICAgIH0pLmxhenkoKVxuXG4gICAgY29uc3Qgc2NoZW1hID0ge1xuICAgICAgZmllbGRzOiBbXG4gICAgICAgIHsgbmFtZTogXCJuYW1lMVwiLCB0eXBlOiBcImludGVnZXJcIiwgZ3JvdXBDaGFyOiBcIi5cIiB9LFxuICAgICAgICB7IG5hbWU6IFwibmFtZTJcIiwgdHlwZTogXCJudW1iZXJcIiwgZGVjaW1hbENoYXI6IFwiLFwiLCBncm91cENoYXI6IFwiLlwiIH0sXG4gICAgICBdLFxuICAgIH1cblxuICAgIGV4cGVjdChhd2FpdCBpbmZlclNjaGVtYUZyb21UYWJsZSh0YWJsZSwgeyBjb21tYURlY2ltYWw6IHRydWUgfSkpLnRvRXF1YWwoXG4gICAgICBzY2hlbWEsXG4gICAgKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIGluZmVyIGJvb2xlYW5zXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0YWJsZSA9IERhdGFGcmFtZSh7XG4gICAgICBuYW1lMTogW1widHJ1ZVwiLCBcIlRydWVcIiwgXCJUUlVFXCJdLFxuICAgICAgbmFtZTI6IFtcImZhbHNlXCIsIFwiRmFsc2VcIiwgXCJGQUxTRVwiXSxcbiAgICB9KS5sYXp5KClcblxuICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgIGZpZWxkczogW1xuICAgICAgICB7IG5hbWU6IFwibmFtZTFcIiwgdHlwZTogXCJib29sZWFuXCIgfSxcbiAgICAgICAgeyBuYW1lOiBcIm5hbWUyXCIsIHR5cGU6IFwiYm9vbGVhblwiIH0sXG4gICAgICBdLFxuICAgIH1cblxuICAgIGV4cGVjdChhd2FpdCBpbmZlclNjaGVtYUZyb21UYWJsZSh0YWJsZSkpLnRvRXF1YWwoc2NoZW1hKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIGluZmVyIG9iamVjdHNcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHRhYmxlID0gRGF0YUZyYW1lKHtcbiAgICAgIG5hbWUxOiBbJ3tcImFcIjogMX0nXSxcbiAgICAgIG5hbWUyOiBbXCJ7fVwiXSxcbiAgICB9KS5sYXp5KClcblxuICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgIGZpZWxkczogW1xuICAgICAgICB7IG5hbWU6IFwibmFtZTFcIiwgdHlwZTogXCJvYmplY3RcIiB9LFxuICAgICAgICB7IG5hbWU6IFwibmFtZTJcIiwgdHlwZTogXCJvYmplY3RcIiB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBleHBlY3QoYXdhaXQgaW5mZXJTY2hlbWFGcm9tVGFibGUodGFibGUpKS50b0VxdWFsKHNjaGVtYSlcbiAgfSlcblxuICBpdChcInNob3VsZCBpbmZlciBhcnJheXNcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHRhYmxlID0gRGF0YUZyYW1lKHtcbiAgICAgIG5hbWUxOiBbXCJbMSwyLDNdXCJdLFxuICAgICAgbmFtZTI6IFtcIltdXCJdLFxuICAgIH0pLmxhenkoKVxuXG4gICAgY29uc3Qgc2NoZW1hID0ge1xuICAgICAgZmllbGRzOiBbXG4gICAgICAgIHsgbmFtZTogXCJuYW1lMVwiLCB0eXBlOiBcImFycmF5XCIgfSxcbiAgICAgICAgeyBuYW1lOiBcIm5hbWUyXCIsIHR5cGU6IFwiYXJyYXlcIiB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBleHBlY3QoYXdhaXQgaW5mZXJTY2hlbWFGcm9tVGFibGUodGFibGUpKS50b0VxdWFsKHNjaGVtYSlcbiAgfSlcblxuICBpdChcInNob3VsZCBpbmZlciBkYXRlcyB3aXRoIElTTyBmb3JtYXRcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHRhYmxlID0gRGF0YUZyYW1lKHtcbiAgICAgIG5hbWUxOiBbXCIyMDIzLTAxLTE1XCIsIFwiMjAyMy0wMi0yMFwiLCBcIjIwMjMtMDMtMjVcIl0sXG4gICAgfSkubGF6eSgpXG5cbiAgICBjb25zdCBzY2hlbWEgPSB7XG4gICAgICBmaWVsZHM6IFt7IG5hbWU6IFwibmFtZTFcIiwgdHlwZTogXCJkYXRlXCIgfV0sXG4gICAgfVxuXG4gICAgZXhwZWN0KGF3YWl0IGluZmVyU2NoZW1hRnJvbVRhYmxlKHRhYmxlKSkudG9FcXVhbChzY2hlbWEpXG4gIH0pXG5cbiAgaXQoXCJzaG91bGQgaW5mZXIgZGF0ZXMgd2l0aCBzbGFzaCBmb3JtYXRcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHRhYmxlID0gRGF0YUZyYW1lKHtcbiAgICAgIHllYXJGaXJzdDogW1wiMjAyMy8wMS8xNVwiLCBcIjIwMjMvMDIvMjBcIiwgXCIyMDIzLzAzLzI1XCJdLFxuICAgICAgZGF5TW9udGg6IFtcIjE1LzAxLzIwMjNcIiwgXCIyMC8wMi8yMDIzXCIsIFwiMjUvMDMvMjAyM1wiXSxcbiAgICAgIG1vbnRoRGF5OiBbXCIwMS8xNS8yMDIzXCIsIFwiMDIvMjAvMjAyM1wiLCBcIjAzLzI1LzIwMjNcIl0sXG4gICAgfSkubGF6eSgpXG5cbiAgICBjb25zdCBzY2hlbWFEZWZhdWx0ID0ge1xuICAgICAgZmllbGRzOiBbXG4gICAgICAgIHsgbmFtZTogXCJ5ZWFyRmlyc3RcIiwgdHlwZTogXCJkYXRlXCIsIGZvcm1hdDogXCIlWS8lbS8lZFwiIH0sXG4gICAgICAgIHsgbmFtZTogXCJkYXlNb250aFwiLCB0eXBlOiBcImRhdGVcIiwgZm9ybWF0OiBcIiVkLyVtLyVZXCIgfSxcbiAgICAgICAgeyBuYW1lOiBcIm1vbnRoRGF5XCIsIHR5cGU6IFwiZGF0ZVwiLCBmb3JtYXQ6IFwiJWQvJW0vJVlcIiB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBjb25zdCBzY2hlbWFNb250aEZpcnN0ID0ge1xuICAgICAgZmllbGRzOiBbXG4gICAgICAgIHsgbmFtZTogXCJ5ZWFyRmlyc3RcIiwgdHlwZTogXCJkYXRlXCIsIGZvcm1hdDogXCIlWS8lbS8lZFwiIH0sXG4gICAgICAgIHsgbmFtZTogXCJkYXlNb250aFwiLCB0eXBlOiBcImRhdGVcIiwgZm9ybWF0OiBcIiVtLyVkLyVZXCIgfSxcbiAgICAgICAgeyBuYW1lOiBcIm1vbnRoRGF5XCIsIHR5cGU6IFwiZGF0ZVwiLCBmb3JtYXQ6IFwiJW0vJWQvJVlcIiB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBleHBlY3QoYXdhaXQgaW5mZXJTY2hlbWFGcm9tVGFibGUodGFibGUpKS50b0VxdWFsKHNjaGVtYURlZmF1bHQpXG4gICAgZXhwZWN0KGF3YWl0IGluZmVyU2NoZW1hRnJvbVRhYmxlKHRhYmxlLCB7IG1vbnRoRmlyc3Q6IHRydWUgfSkpLnRvRXF1YWwoXG4gICAgICBzY2hlbWFNb250aEZpcnN0LFxuICAgIClcbiAgfSlcblxuICBpdChcInNob3VsZCBpbmZlciBkYXRlcyB3aXRoIGh5cGhlbiBmb3JtYXRcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHRhYmxlID0gRGF0YUZyYW1lKHtcbiAgICAgIGRheU1vbnRoOiBbXCIxNS0wMS0yMDIzXCIsIFwiMjAtMDItMjAyM1wiLCBcIjI1LTAzLTIwMjNcIl0sXG4gICAgfSkubGF6eSgpXG5cbiAgICBjb25zdCBzY2hlbWFEZWZhdWx0ID0ge1xuICAgICAgZmllbGRzOiBbeyBuYW1lOiBcImRheU1vbnRoXCIsIHR5cGU6IFwiZGF0ZVwiLCBmb3JtYXQ6IFwiJWQtJW0tJVlcIiB9XSxcbiAgICB9XG5cbiAgICBjb25zdCBzY2hlbWFNb250aEZpcnN0ID0ge1xuICAgICAgZmllbGRzOiBbeyBuYW1lOiBcImRheU1vbnRoXCIsIHR5cGU6IFwiZGF0ZVwiLCBmb3JtYXQ6IFwiJW0tJWQtJVlcIiB9XSxcbiAgICB9XG5cbiAgICBleHBlY3QoYXdhaXQgaW5mZXJTY2hlbWFGcm9tVGFibGUodGFibGUpKS50b0VxdWFsKHNjaGVtYURlZmF1bHQpXG4gICAgZXhwZWN0KGF3YWl0IGluZmVyU2NoZW1hRnJvbVRhYmxlKHRhYmxlLCB7IG1vbnRoRmlyc3Q6IHRydWUgfSkpLnRvRXF1YWwoXG4gICAgICBzY2hlbWFNb250aEZpcnN0LFxuICAgIClcbiAgfSlcblxuICBpdChcInNob3VsZCBpbmZlciB0aW1lcyB3aXRoIHN0YW5kYXJkIGZvcm1hdFwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdGFibGUgPSBEYXRhRnJhbWUoe1xuICAgICAgZnVsbFRpbWU6IFtcIjE0OjMwOjQ1XCIsIFwiMDg6MTU6MzBcIiwgXCIyMzo1OTo1OVwiXSxcbiAgICAgIHNob3J0VGltZTogW1wiMTQ6MzBcIiwgXCIwODoxNVwiLCBcIjIzOjU5XCJdLFxuICAgIH0pLmxhenkoKVxuXG4gICAgY29uc3Qgc2NoZW1hID0ge1xuICAgICAgZmllbGRzOiBbXG4gICAgICAgIHsgbmFtZTogXCJmdWxsVGltZVwiLCB0eXBlOiBcInRpbWVcIiB9LFxuICAgICAgICB7IG5hbWU6IFwic2hvcnRUaW1lXCIsIHR5cGU6IFwidGltZVwiLCBmb3JtYXQ6IFwiJUg6JU1cIiB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBleHBlY3QoYXdhaXQgaW5mZXJTY2hlbWFGcm9tVGFibGUodGFibGUpKS50b0VxdWFsKHNjaGVtYSlcbiAgfSlcblxuICBpdChcInNob3VsZCBpbmZlciB0aW1lcyB3aXRoIDEyLWhvdXIgZm9ybWF0XCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0YWJsZSA9IERhdGFGcmFtZSh7XG4gICAgICBmdWxsVGltZTogW1wiMjozMDo0NSBQTVwiLCBcIjg6MTU6MzAgQU1cIiwgXCIxMTo1OTo1OSBQTVwiXSxcbiAgICAgIHNob3J0VGltZTogW1wiMjozMCBQTVwiLCBcIjg6MTUgQU1cIiwgXCIxMTo1OSBQTVwiXSxcbiAgICB9KS5sYXp5KClcblxuICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgIGZpZWxkczogW1xuICAgICAgICB7IG5hbWU6IFwiZnVsbFRpbWVcIiwgdHlwZTogXCJ0aW1lXCIsIGZvcm1hdDogXCIlSTolTTolUyAlcFwiIH0sXG4gICAgICAgIHsgbmFtZTogXCJzaG9ydFRpbWVcIiwgdHlwZTogXCJ0aW1lXCIsIGZvcm1hdDogXCIlSTolTSAlcFwiIH0sXG4gICAgICBdLFxuICAgIH1cblxuICAgIGV4cGVjdChhd2FpdCBpbmZlclNjaGVtYUZyb21UYWJsZSh0YWJsZSkpLnRvRXF1YWwoc2NoZW1hKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIGluZmVyIHRpbWVzIHdpdGggdGltZXpvbmUgb2Zmc2V0XCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0YWJsZSA9IERhdGFGcmFtZSh7XG4gICAgICBuYW1lOiBbXCIxNDozMDo0NSswMTowMFwiLCBcIjA4OjE1OjMwLTA1OjAwXCIsIFwiMjM6NTk6NTkrMDA6MDBcIl0sXG4gICAgfSkubGF6eSgpXG5cbiAgICBjb25zdCBzY2hlbWEgPSB7XG4gICAgICBmaWVsZHM6IFt7IG5hbWU6IFwibmFtZVwiLCB0eXBlOiBcInRpbWVcIiB9XSxcbiAgICB9XG5cbiAgICBleHBlY3QoYXdhaXQgaW5mZXJTY2hlbWFGcm9tVGFibGUodGFibGUpKS50b0VxdWFsKHNjaGVtYSlcbiAgfSlcblxuICBpdChcInNob3VsZCBpbmZlciBkYXRldGltZXMgd2l0aCBJU08gZm9ybWF0XCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0YWJsZSA9IERhdGFGcmFtZSh7XG4gICAgICBzdGFuZGFyZDogW1xuICAgICAgICBcIjIwMjMtMDEtMTVUMTQ6MzA6NDVcIixcbiAgICAgICAgXCIyMDIzLTAyLTIwVDA4OjE1OjMwXCIsXG4gICAgICAgIFwiMjAyMy0wMy0yNVQyMzo1OTo1OVwiLFxuICAgICAgXSxcbiAgICAgIHV0YzogW1xuICAgICAgICBcIjIwMjMtMDEtMTVUMTQ6MzA6NDVaXCIsXG4gICAgICAgIFwiMjAyMy0wMi0yMFQwODoxNTozMFpcIixcbiAgICAgICAgXCIyMDIzLTAzLTI1VDIzOjU5OjU5WlwiLFxuICAgICAgXSxcbiAgICAgIHdpdGhUejogW1xuICAgICAgICBcIjIwMjMtMDEtMTVUMTQ6MzA6NDUrMDE6MDBcIixcbiAgICAgICAgXCIyMDIzLTAyLTIwVDA4OjE1OjMwLTA1OjAwXCIsXG4gICAgICAgIFwiMjAyMy0wMy0yNVQyMzo1OTo1OSswMDowMFwiLFxuICAgICAgXSxcbiAgICAgIHdpdGhTcGFjZTogW1xuICAgICAgICBcIjIwMjMtMDEtMTUgMTQ6MzA6NDVcIixcbiAgICAgICAgXCIyMDIzLTAyLTIwIDA4OjE1OjMwXCIsXG4gICAgICAgIFwiMjAyMy0wMy0yNSAyMzo1OTo1OVwiLFxuICAgICAgXSxcbiAgICB9KS5sYXp5KClcblxuICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgIGZpZWxkczogW1xuICAgICAgICB7IG5hbWU6IFwic3RhbmRhcmRcIiwgdHlwZTogXCJkYXRldGltZVwiIH0sXG4gICAgICAgIHsgbmFtZTogXCJ1dGNcIiwgdHlwZTogXCJkYXRldGltZVwiIH0sXG4gICAgICAgIHsgbmFtZTogXCJ3aXRoVHpcIiwgdHlwZTogXCJkYXRldGltZVwiIH0sXG4gICAgICAgIHsgbmFtZTogXCJ3aXRoU3BhY2VcIiwgdHlwZTogXCJkYXRldGltZVwiLCBmb3JtYXQ6IFwiJVktJW0tJWQgJUg6JU06JVNcIiB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBleHBlY3QoYXdhaXQgaW5mZXJTY2hlbWFGcm9tVGFibGUodGFibGUpKS50b0VxdWFsKHNjaGVtYSlcbiAgfSlcblxuICBpdChcInNob3VsZCBpbmZlciBkYXRldGltZXMgd2l0aCBjdXN0b20gZm9ybWF0c1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdGFibGUgPSBEYXRhRnJhbWUoe1xuICAgICAgc2hvcnREYXlNb250aDogW1xuICAgICAgICBcIjE1LzAxLzIwMjMgMTQ6MzBcIixcbiAgICAgICAgXCIyMC8wMi8yMDIzIDA4OjE1XCIsXG4gICAgICAgIFwiMjUvMDMvMjAyMyAyMzo1OVwiLFxuICAgICAgXSxcbiAgICAgIGZ1bGxEYXlNb250aDogW1xuICAgICAgICBcIjE1LzAxLzIwMjMgMTQ6MzA6NDVcIixcbiAgICAgICAgXCIyMC8wMi8yMDIzIDA4OjE1OjMwXCIsXG4gICAgICAgIFwiMjUvMDMvMjAyMyAyMzo1OTo1OVwiLFxuICAgICAgXSxcbiAgICAgIHNob3J0TW9udGhEYXk6IFtcbiAgICAgICAgXCIwMS8xNS8yMDIzIDE0OjMwXCIsXG4gICAgICAgIFwiMDIvMjAvMjAyMyAwODoxNVwiLFxuICAgICAgICBcIjAzLzI1LzIwMjMgMjM6NTlcIixcbiAgICAgIF0sXG4gICAgICBmdWxsTW9udGhEYXk6IFtcbiAgICAgICAgXCIwMS8xNS8yMDIzIDE0OjMwOjQ1XCIsXG4gICAgICAgIFwiMDIvMjAvMjAyMyAwODoxNTozMFwiLFxuICAgICAgICBcIjAzLzI1LzIwMjMgMjM6NTk6NTlcIixcbiAgICAgIF0sXG4gICAgfSkubGF6eSgpXG5cbiAgICBjb25zdCBzY2hlbWFEZWZhdWx0ID0ge1xuICAgICAgZmllbGRzOiBbXG4gICAgICAgIHsgbmFtZTogXCJzaG9ydERheU1vbnRoXCIsIHR5cGU6IFwiZGF0ZXRpbWVcIiwgZm9ybWF0OiBcIiVkLyVtLyVZICVIOiVNXCIgfSxcbiAgICAgICAgeyBuYW1lOiBcImZ1bGxEYXlNb250aFwiLCB0eXBlOiBcImRhdGV0aW1lXCIsIGZvcm1hdDogXCIlZC8lbS8lWSAlSDolTTolU1wiIH0sXG4gICAgICAgIHsgbmFtZTogXCJzaG9ydE1vbnRoRGF5XCIsIHR5cGU6IFwiZGF0ZXRpbWVcIiwgZm9ybWF0OiBcIiVkLyVtLyVZICVIOiVNXCIgfSxcbiAgICAgICAgeyBuYW1lOiBcImZ1bGxNb250aERheVwiLCB0eXBlOiBcImRhdGV0aW1lXCIsIGZvcm1hdDogXCIlZC8lbS8lWSAlSDolTTolU1wiIH0sXG4gICAgICBdLFxuICAgIH1cblxuICAgIGNvbnN0IHNjaGVtYU1vbnRoRmlyc3QgPSB7XG4gICAgICBmaWVsZHM6IFtcbiAgICAgICAgeyBuYW1lOiBcInNob3J0RGF5TW9udGhcIiwgdHlwZTogXCJkYXRldGltZVwiLCBmb3JtYXQ6IFwiJW0vJWQvJVkgJUg6JU1cIiB9LFxuICAgICAgICB7IG5hbWU6IFwiZnVsbERheU1vbnRoXCIsIHR5cGU6IFwiZGF0ZXRpbWVcIiwgZm9ybWF0OiBcIiVtLyVkLyVZICVIOiVNOiVTXCIgfSxcbiAgICAgICAgeyBuYW1lOiBcInNob3J0TW9udGhEYXlcIiwgdHlwZTogXCJkYXRldGltZVwiLCBmb3JtYXQ6IFwiJW0vJWQvJVkgJUg6JU1cIiB9LFxuICAgICAgICB7IG5hbWU6IFwiZnVsbE1vbnRoRGF5XCIsIHR5cGU6IFwiZGF0ZXRpbWVcIiwgZm9ybWF0OiBcIiVtLyVkLyVZICVIOiVNOiVTXCIgfSxcbiAgICAgIF0sXG4gICAgfVxuXG4gICAgZXhwZWN0KGF3YWl0IGluZmVyU2NoZW1hRnJvbVRhYmxlKHRhYmxlKSkudG9FcXVhbChzY2hlbWFEZWZhdWx0KVxuICAgIGV4cGVjdChhd2FpdCBpbmZlclNjaGVtYUZyb21UYWJsZSh0YWJsZSwgeyBtb250aEZpcnN0OiB0cnVlIH0pKS50b0VxdWFsKFxuICAgICAgc2NoZW1hTW9udGhGaXJzdCxcbiAgICApXG4gIH0pXG5cbiAgaXQoXCJzaG91bGQgaW5mZXIgbGlzdHNcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHRhYmxlID0gRGF0YUZyYW1lKHtcbiAgICAgIG51bWVyaWNMaXN0OiBbXCIxLjUsMi4zXCIsIFwiNC4xLDUuOVwiLCBcIjcuMiw4LjZcIl0sXG4gICAgICBpbnRlZ2VyTGlzdDogW1wiMSwyXCIsIFwiMyw0XCIsIFwiNSw2XCJdLFxuICAgICAgc2luZ2xlVmFsdWU6IFtcIjEuNVwiLCBcIjIuM1wiLCBcIjQuMVwiXSxcbiAgICB9KS5sYXp5KClcblxuICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgIGZpZWxkczogW1xuICAgICAgICB7IG5hbWU6IFwibnVtZXJpY0xpc3RcIiwgdHlwZTogXCJsaXN0XCIsIGl0ZW1UeXBlOiBcIm51bWJlclwiIH0sXG4gICAgICAgIHsgbmFtZTogXCJpbnRlZ2VyTGlzdFwiLCB0eXBlOiBcImxpc3RcIiwgaXRlbVR5cGU6IFwiaW50ZWdlclwiIH0sXG4gICAgICAgIHsgbmFtZTogXCJzaW5nbGVWYWx1ZVwiLCB0eXBlOiBcIm51bWJlclwiIH0sXG4gICAgICBdLFxuICAgICAgbWlzc2luZ1ZhbHVlczogdW5kZWZpbmVkLFxuICAgIH1cblxuICAgIGV4cGVjdChhd2FpdCBpbmZlclNjaGVtYUZyb21UYWJsZSh0YWJsZSkpLnRvRXF1YWwoc2NoZW1hKVxuICB9KVxufSlcbiJdfQ==