UNPKG

@dpkit/table

Version:

Data Package implementation in TypeScript.

244 lines 32.7 kB
import { DataFrame, Series } from "nodejs-polars"; import { DataType } from "nodejs-polars"; import { describe, expect, it } from "vitest"; import { inferSchema } from "./infer.js"; describe("inferSchema", () => { 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 inferSchema(table)).toEqual(schema); }); it("should infer numeric", async () => { const table = DataFrame({ name1: ["1", "2", "3"], name2: ["1,1", "2,2", "3,3"], 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 inferSchema(table)).toEqual(schema); }); it("should infer numeric (commaDecimal)", async () => { const table = DataFrame({ name1: ["1.1", "2.2", "3.3"], name2: ["1.1,0", "2.2,0", "3.3,0"], }).lazy(); const schema = { fields: [ { name: "name1", type: "integer", groupChar: "." }, { name: "name2", type: "number", decimalChar: ",", groupChar: "." }, ], }; expect(await inferSchema(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 inferSchema(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 inferSchema(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 inferSchema(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 inferSchema(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 inferSchema(table)).toEqual(schemaDefault); expect(await inferSchema(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 inferSchema(table)).toEqual(schemaDefault); expect(await inferSchema(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 inferSchema(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 inferSchema(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 inferSchema(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 inferSchema(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 inferSchema(table)).toEqual(schemaDefault); expect(await inferSchema(table, { monthFirst: true })).toEqual(schemaMonthFirst); }); }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5mZXIuc3BlYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NjaGVtYS9pbmZlci5zcGVjLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFBO0FBQ2pELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUE7QUFDeEMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLE1BQU0sUUFBUSxDQUFBO0FBQzdDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFFeEMsUUFBUSxDQUFDLGFBQWEsRUFBRSxHQUFHLEVBQUU7SUFDM0IsRUFBRSxDQUFDLGdDQUFnQyxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQzlDLE1BQU0sS0FBSyxHQUFHLFNBQVMsQ0FBQztZQUN0QixPQUFPLEVBQUUsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDO1lBQ2xELE1BQU0sRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUM7U0FDbkIsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFBO1FBRVQsTUFBTSxNQUFNLEdBQUc7WUFDYixNQUFNLEVBQUU7Z0JBQ04sRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUU7Z0JBQ3BDLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO2FBQ25DO1NBQ0YsQ0FBQTtRQUVELE1BQU0sQ0FBQyxNQUFNLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUNsRCxDQUFDLENBQUMsQ0FBQTtJQUVGLEVBQUUsQ0FBQyxzQkFBc0IsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNwQyxNQUFNLEtBQUssR0FBRyxTQUFTLENBQUM7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QixNQUFNLEVBQUU7Z0JBQ04sRUFBRSxJQUFJLEVBQUUsZUFBZSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLGdCQUFnQixFQUFFO2dCQUNyRSxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsbUJBQW1CLEVBQUU7Z0JBQ3ZFLEVBQUUsSUFBSSxFQUFFLGVBQWUsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxnQkFBZ0IsRUFBRTtnQkFDckUsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLG1CQUFtQixFQUFFO2FBQ3hFO1NBQ0YsQ0FBQTtRQUVELE1BQU0sQ0FBQyxNQUFNLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQTtRQUN2RCxNQUFNLENBQUMsTUFBTSxXQUFXLENBQUMsS0FBSyxFQUFFLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQzVELGdCQUFnQixDQUNqQixDQUFBO0lBQ0gsQ0FBQyxDQUFDLENBQUE7QUFDSixDQUFDLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERhdGFGcmFtZSwgU2VyaWVzIH0gZnJvbSBcIm5vZGVqcy1wb2xhcnNcIlxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tIFwibm9kZWpzLXBvbGFyc1wiXG5pbXBvcnQgeyBkZXNjcmliZSwgZXhwZWN0LCBpdCB9IGZyb20gXCJ2aXRlc3RcIlxuaW1wb3J0IHsgaW5mZXJTY2hlbWEgfSBmcm9tIFwiLi9pbmZlci50c1wiXG5cbmRlc2NyaWJlKFwiaW5mZXJTY2hlbWFcIiwgKCkgPT4ge1xuICBpdChcInNob3VsZCBpbmZlciBmcm9tIG5hdGl2ZSB0eXBlc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdGFibGUgPSBEYXRhRnJhbWUoe1xuICAgICAgaW50ZWdlcjogU2VyaWVzKFwiaW50ZWdlclwiLCBbMSwgMl0sIERhdGFUeXBlLkludDMyKSxcbiAgICAgIG51bWJlcjogWzEuMSwgMi4yXSxcbiAgICB9KS5sYXp5KClcblxuICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgIGZpZWxkczogW1xuICAgICAgICB7IG5hbWU6IFwiaW50ZWdlclwiLCB0eXBlOiBcImludGVnZXJcIiB9LFxuICAgICAgICB7IG5hbWU6IFwibnVtYmVyXCIsIHR5cGU6IFwibnVtYmVyXCIgfSxcbiAgICAgIF0sXG4gICAgfVxuXG4gICAgZXhwZWN0KGF3YWl0IGluZmVyU2NoZW1hKHRhYmxlKSkudG9FcXVhbChzY2hlbWEpXG4gIH0pXG5cbiAgaXQoXCJzaG91bGQgaW5mZXIgbnVtZXJpY1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdGFibGUgPSBEYXRhRnJhbWUoe1xuICAgICAgbmFtZTE6IFtcIjFcIiwgXCIyXCIsIFwiM1wiXSxcbiAgICAgIG5hbWUyOiBbXCIxLDFcIiwgXCIyLDJcIiwgXCIzLDNcIl0sXG4gICAgICBuYW1lMzogW1wiMS4xXCIsIFwiMi4yXCIsIFwiMy4zXCJdLFxuICAgICAgbmFtZTQ6IFtcIjEsMDAwLjFcIiwgXCIyLDAwMC4yXCIsIFwiMywwMDAuM1wiXSxcbiAgICB9KS5sYXp5KClcblxuICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgIGZpZWxkczogW1xuICAgICAgICB7IG5hbWU6IFwibmFtZTFcIiwgdHlwZTogXCJpbnRlZ2VyXCIgfSxcbiAgICAgICAgeyBuYW1lOiBcIm5hbWUyXCIsIHR5cGU6IFwiaW50ZWdlclwiLCBncm91cENoYXI6IFwiLFwiIH0sXG4gICAgICAgIHsgbmFtZTogXCJuYW1lM1wiLCB0eXBlOiBcIm51bWJlclwiIH0sXG4gICAgICAgIHsgbmFtZTogXCJuYW1lNFwiLCB0eXBlOiBcIm51bWJlclwiLCBncm91cENoYXI6IFwiLFwiIH0sXG4gICAgICBdLFxuICAgIH1cblxuICAgIGV4cGVjdChhd2FpdCBpbmZlclNjaGVtYSh0YWJsZSkpLnRvRXF1YWwoc2NoZW1hKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIGluZmVyIG51bWVyaWMgKGNvbW1hRGVjaW1hbClcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHRhYmxlID0gRGF0YUZyYW1lKHtcbiAgICAgIG5hbWUxOiBbXCIxLjFcIiwgXCIyLjJcIiwgXCIzLjNcIl0sXG4gICAgICBuYW1lMjogW1wiMS4xLDBcIiwgXCIyLjIsMFwiLCBcIjMuMywwXCJdLFxuICAgIH0pLmxhenkoKVxuXG4gICAgY29uc3Qgc2NoZW1hID0ge1xuICAgICAgZmllbGRzOiBbXG4gICAgICAgIHsgbmFtZTogXCJuYW1lMVwiLCB0eXBlOiBcImludGVnZXJcIiwgZ3JvdXBDaGFyOiBcIi5cIiB9LFxuICAgICAgICB7IG5hbWU6IFwibmFtZTJcIiwgdHlwZTogXCJudW1iZXJcIiwgZGVjaW1hbENoYXI6IFwiLFwiLCBncm91cENoYXI6IFwiLlwiIH0sXG4gICAgICBdLFxuICAgIH1cblxuICAgIGV4cGVjdChhd2FpdCBpbmZlclNjaGVtYSh0YWJsZSwgeyBjb21tYURlY2ltYWw6IHRydWUgfSkpLnRvRXF1YWwoc2NoZW1hKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIGluZmVyIGJvb2xlYW5zXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0YWJsZSA9IERhdGFGcmFtZSh7XG4gICAgICBuYW1lMTogW1widHJ1ZVwiLCBcIlRydWVcIiwgXCJUUlVFXCJdLFxuICAgICAgbmFtZTI6IFtcImZhbHNlXCIsIFwiRmFsc2VcIiwgXCJGQUxTRVwiXSxcbiAgICB9KS5sYXp5KClcblxuICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgIGZpZWxkczogW1xuICAgICAgICB7IG5hbWU6IFwibmFtZTFcIiwgdHlwZTogXCJib29sZWFuXCIgfSxcbiAgICAgICAgeyBuYW1lOiBcIm5hbWUyXCIsIHR5cGU6IFwiYm9vbGVhblwiIH0sXG4gICAgICBdLFxuICAgIH1cblxuICAgIGV4cGVjdChhd2FpdCBpbmZlclNjaGVtYSh0YWJsZSkpLnRvRXF1YWwoc2NoZW1hKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIGluZmVyIG9iamVjdHNcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHRhYmxlID0gRGF0YUZyYW1lKHtcbiAgICAgIG5hbWUxOiBbJ3tcImFcIjogMX0nXSxcbiAgICAgIG5hbWUyOiBbXCJ7fVwiXSxcbiAgICB9KS5sYXp5KClcblxuICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgIGZpZWxkczogW1xuICAgICAgICB7IG5hbWU6IFwibmFtZTFcIiwgdHlwZTogXCJvYmplY3RcIiB9LFxuICAgICAgICB7IG5hbWU6IFwibmFtZTJcIiwgdHlwZTogXCJvYmplY3RcIiB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBleHBlY3QoYXdhaXQgaW5mZXJTY2hlbWEodGFibGUpKS50b0VxdWFsKHNjaGVtYSlcbiAgfSlcblxuICBpdChcInNob3VsZCBpbmZlciBhcnJheXNcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHRhYmxlID0gRGF0YUZyYW1lKHtcbiAgICAgIG5hbWUxOiBbXCJbMSwyLDNdXCJdLFxuICAgICAgbmFtZTI6IFtcIltdXCJdLFxuICAgIH0pLmxhenkoKVxuXG4gICAgY29uc3Qgc2NoZW1hID0ge1xuICAgICAgZmllbGRzOiBbXG4gICAgICAgIHsgbmFtZTogXCJuYW1lMVwiLCB0eXBlOiBcImFycmF5XCIgfSxcbiAgICAgICAgeyBuYW1lOiBcIm5hbWUyXCIsIHR5cGU6IFwiYXJyYXlcIiB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBleHBlY3QoYXdhaXQgaW5mZXJTY2hlbWEodGFibGUpKS50b0VxdWFsKHNjaGVtYSlcbiAgfSlcblxuICBpdChcInNob3VsZCBpbmZlciBkYXRlcyB3aXRoIElTTyBmb3JtYXRcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHRhYmxlID0gRGF0YUZyYW1lKHtcbiAgICAgIG5hbWUxOiBbXCIyMDIzLTAxLTE1XCIsIFwiMjAyMy0wMi0yMFwiLCBcIjIwMjMtMDMtMjVcIl0sXG4gICAgfSkubGF6eSgpXG5cbiAgICBjb25zdCBzY2hlbWEgPSB7XG4gICAgICBmaWVsZHM6IFt7IG5hbWU6IFwibmFtZTFcIiwgdHlwZTogXCJkYXRlXCIgfV0sXG4gICAgfVxuXG4gICAgZXhwZWN0KGF3YWl0IGluZmVyU2NoZW1hKHRhYmxlKSkudG9FcXVhbChzY2hlbWEpXG4gIH0pXG5cbiAgaXQoXCJzaG91bGQgaW5mZXIgZGF0ZXMgd2l0aCBzbGFzaCBmb3JtYXRcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHRhYmxlID0gRGF0YUZyYW1lKHtcbiAgICAgIHllYXJGaXJzdDogW1wiMjAyMy8wMS8xNVwiLCBcIjIwMjMvMDIvMjBcIiwgXCIyMDIzLzAzLzI1XCJdLFxuICAgICAgZGF5TW9udGg6IFtcIjE1LzAxLzIwMjNcIiwgXCIyMC8wMi8yMDIzXCIsIFwiMjUvMDMvMjAyM1wiXSxcbiAgICAgIG1vbnRoRGF5OiBbXCIwMS8xNS8yMDIzXCIsIFwiMDIvMjAvMjAyM1wiLCBcIjAzLzI1LzIwMjNcIl0sXG4gICAgfSkubGF6eSgpXG5cbiAgICBjb25zdCBzY2hlbWFEZWZhdWx0ID0ge1xuICAgICAgZmllbGRzOiBbXG4gICAgICAgIHsgbmFtZTogXCJ5ZWFyRmlyc3RcIiwgdHlwZTogXCJkYXRlXCIsIGZvcm1hdDogXCIlWS8lbS8lZFwiIH0sXG4gICAgICAgIHsgbmFtZTogXCJkYXlNb250aFwiLCB0eXBlOiBcImRhdGVcIiwgZm9ybWF0OiBcIiVkLyVtLyVZXCIgfSxcbiAgICAgICAgeyBuYW1lOiBcIm1vbnRoRGF5XCIsIHR5cGU6IFwiZGF0ZVwiLCBmb3JtYXQ6IFwiJWQvJW0vJVlcIiB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBjb25zdCBzY2hlbWFNb250aEZpcnN0ID0ge1xuICAgICAgZmllbGRzOiBbXG4gICAgICAgIHsgbmFtZTogXCJ5ZWFyRmlyc3RcIiwgdHlwZTogXCJkYXRlXCIsIGZvcm1hdDogXCIlWS8lbS8lZFwiIH0sXG4gICAgICAgIHsgbmFtZTogXCJkYXlNb250aFwiLCB0eXBlOiBcImRhdGVcIiwgZm9ybWF0OiBcIiVtLyVkLyVZXCIgfSxcbiAgICAgICAgeyBuYW1lOiBcIm1vbnRoRGF5XCIsIHR5cGU6IFwiZGF0ZVwiLCBmb3JtYXQ6IFwiJW0vJWQvJVlcIiB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBleHBlY3QoYXdhaXQgaW5mZXJTY2hlbWEodGFibGUpKS50b0VxdWFsKHNjaGVtYURlZmF1bHQpXG4gICAgZXhwZWN0KGF3YWl0IGluZmVyU2NoZW1hKHRhYmxlLCB7IG1vbnRoRmlyc3Q6IHRydWUgfSkpLnRvRXF1YWwoXG4gICAgICBzY2hlbWFNb250aEZpcnN0LFxuICAgIClcbiAgfSlcblxuICBpdChcInNob3VsZCBpbmZlciBkYXRlcyB3aXRoIGh5cGhlbiBmb3JtYXRcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHRhYmxlID0gRGF0YUZyYW1lKHtcbiAgICAgIGRheU1vbnRoOiBbXCIxNS0wMS0yMDIzXCIsIFwiMjAtMDItMjAyM1wiLCBcIjI1LTAzLTIwMjNcIl0sXG4gICAgfSkubGF6eSgpXG5cbiAgICBjb25zdCBzY2hlbWFEZWZhdWx0ID0ge1xuICAgICAgZmllbGRzOiBbeyBuYW1lOiBcImRheU1vbnRoXCIsIHR5cGU6IFwiZGF0ZVwiLCBmb3JtYXQ6IFwiJWQtJW0tJVlcIiB9XSxcbiAgICB9XG5cbiAgICBjb25zdCBzY2hlbWFNb250aEZpcnN0ID0ge1xuICAgICAgZmllbGRzOiBbeyBuYW1lOiBcImRheU1vbnRoXCIsIHR5cGU6IFwiZGF0ZVwiLCBmb3JtYXQ6IFwiJW0tJWQtJVlcIiB9XSxcbiAgICB9XG5cbiAgICBleHBlY3QoYXdhaXQgaW5mZXJTY2hlbWEodGFibGUpKS50b0VxdWFsKHNjaGVtYURlZmF1bHQpXG4gICAgZXhwZWN0KGF3YWl0IGluZmVyU2NoZW1hKHRhYmxlLCB7IG1vbnRoRmlyc3Q6IHRydWUgfSkpLnRvRXF1YWwoXG4gICAgICBzY2hlbWFNb250aEZpcnN0LFxuICAgIClcbiAgfSlcblxuICBpdChcInNob3VsZCBpbmZlciB0aW1lcyB3aXRoIHN0YW5kYXJkIGZvcm1hdFwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdGFibGUgPSBEYXRhRnJhbWUoe1xuICAgICAgZnVsbFRpbWU6IFtcIjE0OjMwOjQ1XCIsIFwiMDg6MTU6MzBcIiwgXCIyMzo1OTo1OVwiXSxcbiAgICAgIHNob3J0VGltZTogW1wiMTQ6MzBcIiwgXCIwODoxNVwiLCBcIjIzOjU5XCJdLFxuICAgIH0pLmxhenkoKVxuXG4gICAgY29uc3Qgc2NoZW1hID0ge1xuICAgICAgZmllbGRzOiBbXG4gICAgICAgIHsgbmFtZTogXCJmdWxsVGltZVwiLCB0eXBlOiBcInRpbWVcIiB9LFxuICAgICAgICB7IG5hbWU6IFwic2hvcnRUaW1lXCIsIHR5cGU6IFwidGltZVwiLCBmb3JtYXQ6IFwiJUg6JU1cIiB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBleHBlY3QoYXdhaXQgaW5mZXJTY2hlbWEodGFibGUpKS50b0VxdWFsKHNjaGVtYSlcbiAgfSlcblxuICBpdChcInNob3VsZCBpbmZlciB0aW1lcyB3aXRoIDEyLWhvdXIgZm9ybWF0XCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0YWJsZSA9IERhdGFGcmFtZSh7XG4gICAgICBmdWxsVGltZTogW1wiMjozMDo0NSBQTVwiLCBcIjg6MTU6MzAgQU1cIiwgXCIxMTo1OTo1OSBQTVwiXSxcbiAgICAgIHNob3J0VGltZTogW1wiMjozMCBQTVwiLCBcIjg6MTUgQU1cIiwgXCIxMTo1OSBQTVwiXSxcbiAgICB9KS5sYXp5KClcblxuICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgIGZpZWxkczogW1xuICAgICAgICB7IG5hbWU6IFwiZnVsbFRpbWVcIiwgdHlwZTogXCJ0aW1lXCIsIGZvcm1hdDogXCIlSTolTTolUyAlcFwiIH0sXG4gICAgICAgIHsgbmFtZTogXCJzaG9ydFRpbWVcIiwgdHlwZTogXCJ0aW1lXCIsIGZvcm1hdDogXCIlSTolTSAlcFwiIH0sXG4gICAgICBdLFxuICAgIH1cblxuICAgIGV4cGVjdChhd2FpdCBpbmZlclNjaGVtYSh0YWJsZSkpLnRvRXF1YWwoc2NoZW1hKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIGluZmVyIHRpbWVzIHdpdGggdGltZXpvbmUgb2Zmc2V0XCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0YWJsZSA9IERhdGFGcmFtZSh7XG4gICAgICBuYW1lOiBbXCIxNDozMDo0NSswMTowMFwiLCBcIjA4OjE1OjMwLTA1OjAwXCIsIFwiMjM6NTk6NTkrMDA6MDBcIl0sXG4gICAgfSkubGF6eSgpXG5cbiAgICBjb25zdCBzY2hlbWEgPSB7XG4gICAgICBmaWVsZHM6IFt7IG5hbWU6IFwibmFtZVwiLCB0eXBlOiBcInRpbWVcIiB9XSxcbiAgICB9XG5cbiAgICBleHBlY3QoYXdhaXQgaW5mZXJTY2hlbWEodGFibGUpKS50b0VxdWFsKHNjaGVtYSlcbiAgfSlcblxuICBpdChcInNob3VsZCBpbmZlciBkYXRldGltZXMgd2l0aCBJU08gZm9ybWF0XCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0YWJsZSA9IERhdGFGcmFtZSh7XG4gICAgICBzdGFuZGFyZDogW1xuICAgICAgICBcIjIwMjMtMDEtMTVUMTQ6MzA6NDVcIixcbiAgICAgICAgXCIyMDIzLTAyLTIwVDA4OjE1OjMwXCIsXG4gICAgICAgIFwiMjAyMy0wMy0yNVQyMzo1OTo1OVwiLFxuICAgICAgXSxcbiAgICAgIHV0YzogW1xuICAgICAgICBcIjIwMjMtMDEtMTVUMTQ6MzA6NDVaXCIsXG4gICAgICAgIFwiMjAyMy0wMi0yMFQwODoxNTozMFpcIixcbiAgICAgICAgXCIyMDIzLTAzLTI1VDIzOjU5OjU5WlwiLFxuICAgICAgXSxcbiAgICAgIHdpdGhUejogW1xuICAgICAgICBcIjIwMjMtMDEtMTVUMTQ6MzA6NDUrMDE6MDBcIixcbiAgICAgICAgXCIyMDIzLTAyLTIwVDA4OjE1OjMwLTA1OjAwXCIsXG4gICAgICAgIFwiMjAyMy0wMy0yNVQyMzo1OTo1OSswMDowMFwiLFxuICAgICAgXSxcbiAgICAgIHdpdGhTcGFjZTogW1xuICAgICAgICBcIjIwMjMtMDEtMTUgMTQ6MzA6NDVcIixcbiAgICAgICAgXCIyMDIzLTAyLTIwIDA4OjE1OjMwXCIsXG4gICAgICAgIFwiMjAyMy0wMy0yNSAyMzo1OTo1OVwiLFxuICAgICAgXSxcbiAgICB9KS5sYXp5KClcblxuICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgIGZpZWxkczogW1xuICAgICAgICB7IG5hbWU6IFwic3RhbmRhcmRcIiwgdHlwZTogXCJkYXRldGltZVwiIH0sXG4gICAgICAgIHsgbmFtZTogXCJ1dGNcIiwgdHlwZTogXCJkYXRldGltZVwiIH0sXG4gICAgICAgIHsgbmFtZTogXCJ3aXRoVHpcIiwgdHlwZTogXCJkYXRldGltZVwiIH0sXG4gICAgICAgIHsgbmFtZTogXCJ3aXRoU3BhY2VcIiwgdHlwZTogXCJkYXRldGltZVwiLCBmb3JtYXQ6IFwiJVktJW0tJWQgJUg6JU06JVNcIiB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBleHBlY3QoYXdhaXQgaW5mZXJTY2hlbWEodGFibGUpKS50b0VxdWFsKHNjaGVtYSlcbiAgfSlcblxuICBpdChcInNob3VsZCBpbmZlciBkYXRldGltZXMgd2l0aCBjdXN0b20gZm9ybWF0c1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdGFibGUgPSBEYXRhRnJhbWUoe1xuICAgICAgc2hvcnREYXlNb250aDogW1xuICAgICAgICBcIjE1LzAxLzIwMjMgMTQ6MzBcIixcbiAgICAgICAgXCIyMC8wMi8yMDIzIDA4OjE1XCIsXG4gICAgICAgIFwiMjUvMDMvMjAyMyAyMzo1OVwiLFxuICAgICAgXSxcbiAgICAgIGZ1bGxEYXlNb250aDogW1xuICAgICAgICBcIjE1LzAxLzIwMjMgMTQ6MzA6NDVcIixcbiAgICAgICAgXCIyMC8wMi8yMDIzIDA4OjE1OjMwXCIsXG4gICAgICAgIFwiMjUvMDMvMjAyMyAyMzo1OTo1OVwiLFxuICAgICAgXSxcbiAgICAgIHNob3J0TW9udGhEYXk6IFtcbiAgICAgICAgXCIwMS8xNS8yMDIzIDE0OjMwXCIsXG4gICAgICAgIFwiMDIvMjAvMjAyMyAwODoxNVwiLFxuICAgICAgICBcIjAzLzI1LzIwMjMgMjM6NTlcIixcbiAgICAgIF0sXG4gICAgICBmdWxsTW9udGhEYXk6IFtcbiAgICAgICAgXCIwMS8xNS8yMDIzIDE0OjMwOjQ1XCIsXG4gICAgICAgIFwiMDIvMjAvMjAyMyAwODoxNTozMFwiLFxuICAgICAgICBcIjAzLzI1LzIwMjMgMjM6NTk6NTlcIixcbiAgICAgIF0sXG4gICAgfSkubGF6eSgpXG5cbiAgICBjb25zdCBzY2hlbWFEZWZhdWx0ID0ge1xuICAgICAgZmllbGRzOiBbXG4gICAgICAgIHsgbmFtZTogXCJzaG9ydERheU1vbnRoXCIsIHR5cGU6IFwiZGF0ZXRpbWVcIiwgZm9ybWF0OiBcIiVkLyVtLyVZICVIOiVNXCIgfSxcbiAgICAgICAgeyBuYW1lOiBcImZ1bGxEYXlNb250aFwiLCB0eXBlOiBcImRhdGV0aW1lXCIsIGZvcm1hdDogXCIlZC8lbS8lWSAlSDolTTolU1wiIH0sXG4gICAgICAgIHsgbmFtZTogXCJzaG9ydE1vbnRoRGF5XCIsIHR5cGU6IFwiZGF0ZXRpbWVcIiwgZm9ybWF0OiBcIiVkLyVtLyVZICVIOiVNXCIgfSxcbiAgICAgICAgeyBuYW1lOiBcImZ1bGxNb250aERheVwiLCB0eXBlOiBcImRhdGV0aW1lXCIsIGZvcm1hdDogXCIlZC8lbS8lWSAlSDolTTolU1wiIH0sXG4gICAgICBdLFxuICAgIH1cblxuICAgIGNvbnN0IHNjaGVtYU1vbnRoRmlyc3QgPSB7XG4gICAgICBmaWVsZHM6IFtcbiAgICAgICAgeyBuYW1lOiBcInNob3J0RGF5TW9udGhcIiwgdHlwZTogXCJkYXRldGltZVwiLCBmb3JtYXQ6IFwiJW0vJWQvJVkgJUg6JU1cIiB9LFxuICAgICAgICB7IG5hbWU6IFwiZnVsbERheU1vbnRoXCIsIHR5cGU6IFwiZGF0ZXRpbWVcIiwgZm9ybWF0OiBcIiVtLyVkLyVZICVIOiVNOiVTXCIgfSxcbiAgICAgICAgeyBuYW1lOiBcInNob3J0TW9udGhEYXlcIiwgdHlwZTogXCJkYXRldGltZVwiLCBmb3JtYXQ6IFwiJW0vJWQvJVkgJUg6JU1cIiB9LFxuICAgICAgICB7IG5hbWU6IFwiZnVsbE1vbnRoRGF5XCIsIHR5cGU6IFwiZGF0ZXRpbWVcIiwgZm9ybWF0OiBcIiVtLyVkLyVZICVIOiVNOiVTXCIgfSxcbiAgICAgIF0sXG4gICAgfVxuXG4gICAgZXhwZWN0KGF3YWl0IGluZmVyU2NoZW1hKHRhYmxlKSkudG9FcXVhbChzY2hlbWFEZWZhdWx0KVxuICAgIGV4cGVjdChhd2FpdCBpbmZlclNjaGVtYSh0YWJsZSwgeyBtb250aEZpcnN0OiB0cnVlIH0pKS50b0VxdWFsKFxuICAgICAgc2NoZW1hTW9udGhGaXJzdCxcbiAgICApXG4gIH0pXG59KVxuIl19