UNPKG

@dpkit/table

Version:

Data Package implementation in TypeScript.

118 lines 16.5 kB
import { col } from "nodejs-polars"; import { getPolarsSchema } from "../schema/index.js"; export async function inferSchema(table, options) { const { sampleRows = 100, confidence = 0.9 } = options ?? {}; const schema = { fields: [], }; const typeMapping = createTypeMapping(); const regexMapping = createRegexMapping(options); const sample = await table.head(sampleRows).collect(); const polarsSchema = getPolarsSchema(sample.schema); const failureThreshold = sample.height - Math.floor(sample.height * confidence) || 1; for (const polarsField of polarsSchema.fields) { const name = polarsField.name; const type = typeMapping[polarsField.type.variant] ?? "any"; let field = { name, type }; if (type === "string") { for (const [regex, patch] of Object.entries(regexMapping)) { const failures = sample .filter(col(name).str.contains(regex).not()) .head(failureThreshold).height; if (failures < failureThreshold) { field = { ...field, ...patch }; break; } } } schema.fields.push(field); } return schema; } function createTypeMapping() { const mapping = { Array: "array", Bool: "boolean", Categorical: "string", Date: "date", Datetime: "datetime", Decimal: "number", Float32: "number", Float64: "number", Int16: "integer", Int32: "integer", Int64: "integer", Int8: "integer", List: "array", Null: "any", Object: "object", String: "string", Struct: "object", Time: "time", UInt16: "integer", UInt32: "integer", UInt64: "integer", UInt8: "integer", Utf8: "string", }; return mapping; } function createRegexMapping(options) { const { commaDecimal, monthFirst } = options ?? {}; const mapping = { // Numeric "^\\d+$": { type: "integer" }, "^[,\\d]+$": commaDecimal ? { type: "number" } : { type: "integer", groupChar: "," }, "^\\d+\\.\\d+$": commaDecimal ? { type: "integer", groupChar: "." } : { type: "number" }, "^[,\\d]+\\.\\d+$": { type: "number", groupChar: "," }, "^[.\\d]+\\,\\d+$": { type: "number", groupChar: ".", decimalChar: "," }, // Boolean "^(true|True|TRUE|false|False|FALSE)$": { type: "boolean" }, // Date "^\\d{4}-\\d{2}-\\d{2}$": { type: "date" }, "^\\d{4}/\\d{2}/\\d{2}$": { type: "date", format: "%Y/%m/%d" }, "^\\d{2}/\\d{2}/\\d{4}$": monthFirst ? { type: "date", format: "%m/%d/%Y" } : { type: "date", format: "%d/%m/%Y" }, "^\\d{2}-\\d{2}-\\d{4}$": monthFirst ? { type: "date", format: "%m-%d-%Y" } : { type: "date", format: "%d-%m-%Y" }, "^\\d{2}\\.\\d{2}\\.\\d{4}$": monthFirst ? { type: "date", format: "%m.%d.%Y" } : { type: "date", format: "%d.%m.%Y" }, // Time "^\\d{2}:\\d{2}:\\d{2}$": { type: "time" }, "^\\d{2}:\\d{2}$": { type: "time", format: "%H:%M" }, "^\\d{1,2}:\\d{2}:\\d{2}\\s*(am|pm|AM|PM)$": { type: "time", format: "%I:%M:%S %p", }, "^\\d{1,2}:\\d{2}\\s*(am|pm|AM|PM)$": { type: "time", format: "%I:%M %p" }, "^\\d{2}:\\d{2}:\\d{2}[+-]\\d{2}:?\\d{2}$": { type: "time" }, // Datetime - ISO format "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z?$": { type: "datetime" }, "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}[+-]\\d{2}:?\\d{2}$": { type: "datetime", }, "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$": { type: "datetime", format: "%Y-%m-%d %H:%M:%S", }, "^\\d{2}/\\d{2}/\\d{4} \\d{2}:\\d{2}$": monthFirst ? { type: "datetime", format: "%m/%d/%Y %H:%M" } : { type: "datetime", format: "%d/%m/%Y %H:%M" }, "^\\d{2}/\\d{2}/\\d{4} \\d{2}:\\d{2}:\\d{2}$": monthFirst ? { type: "datetime", format: "%m/%d/%Y %H:%M:%S" } : { type: "datetime", format: "%d/%m/%Y %H:%M:%S" }, // Object "^\\{": { type: "object" }, // Array "^\\[": { type: "array" }, }; return mapping; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5mZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zY2hlbWEvaW5mZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUNuQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sb0JBQW9CLENBQUE7QUFZcEQsTUFBTSxDQUFDLEtBQUssVUFBVSxXQUFXLENBQUMsS0FBWSxFQUFFLE9BQTRCO0lBQzFFLE1BQU0sRUFBRSxVQUFVLEdBQUcsR0FBRyxFQUFFLFVBQVUsR0FBRyxHQUFHLEVBQUUsR0FBRyxPQUFPLElBQUksRUFBRSxDQUFBO0lBQzVELE1BQU0sTUFBTSxHQUFXO1FBQ3JCLE1BQU0sRUFBRSxFQUFFO0tBQ1gsQ0FBQTtJQUVELE1BQU0sV0FBVyxHQUFHLGlCQUFpQixFQUFFLENBQUE7SUFDdkMsTUFBTSxZQUFZLEdBQUcsa0JBQWtCLENBQUMsT0FBTyxDQUFDLENBQUE7SUFFaEQsTUFBTSxNQUFNLEdBQUcsTUFBTSxLQUFLLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFBO0lBQ3JELE1BQU0sWUFBWSxHQUFHLGVBQWUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUE7SUFFbkQsTUFBTSxnQkFBZ0IsR0FDcEIsTUFBTSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFBO0lBRTdELEtBQUssTUFBTSxXQUFXLElBQUksWUFBWSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQzlDLE1BQU0sSUFBSSxHQUFHLFdBQVcsQ0FBQyxJQUFJLENBQUE7UUFDN0IsTUFBTSxJQUFJLEdBQUcsV0FBVyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksS0FBSyxDQUFBO1FBRTNELElBQUksS0FBSyxHQUFHLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFBO1FBRTFCLElBQUksSUFBSSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ3RCLEtBQUssTUFBTSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7Z0JBQzFELE1BQU0sUUFBUSxHQUFHLE1BQU07cUJBQ3BCLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztxQkFDM0MsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsTUFBTSxDQUFBO2dCQUNoQyxJQUFJLFFBQVEsR0FBRyxnQkFBZ0IsRUFBRSxDQUFDO29CQUNoQyxLQUFLLEdBQUcsRUFBRSxHQUFHLEtBQUssRUFBRSxHQUFHLEtBQUssRUFBRSxDQUFBO29CQUM5QixNQUFLO2dCQUNQLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztRQUVELE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQzNCLENBQUM7SUFFRCxPQUFPLE1BQU0sQ0FBQTtBQUNmLENBQUM7QUFFRCxTQUFTLGlCQUFpQjtJQUN4QixNQUFNLE9BQU8sR0FBa0M7UUFDN0MsS0FBSyxFQUFFLE9BQU87UUFDZCxJQUFJLEVBQUUsU0FBUztRQUNmLFdBQVcsRUFBRSxRQUFRO1FBQ3JCLElBQUksRUFBRSxNQUFNO1FBQ1osUUFBUSxFQUFFLFVBQVU7UUFDcEIsT0FBTyxFQUFFLFFBQVE7UUFDakIsT0FBTyxFQUFFLFFBQVE7UUFDakIsT0FBTyxFQUFFLFFBQVE7UUFDakIsS0FBSyxFQUFFLFNBQVM7UUFDaEIsS0FBSyxFQUFFLFNBQVM7UUFDaEIsS0FBSyxFQUFFLFNBQVM7UUFDaEIsSUFBSSxFQUFFLFNBQVM7UUFDZixJQUFJLEVBQUUsT0FBTztRQUNiLElBQUksRUFBRSxLQUFLO1FBQ1gsTUFBTSxFQUFFLFFBQVE7UUFDaEIsTUFBTSxFQUFFLFFBQVE7UUFDaEIsTUFBTSxFQUFFLFFBQVE7UUFDaEIsSUFBSSxFQUFFLE1BQU07UUFDWixNQUFNLEVBQUUsU0FBUztRQUNqQixNQUFNLEVBQUUsU0FBUztRQUNqQixNQUFNLEVBQUUsU0FBUztRQUNqQixLQUFLLEVBQUUsU0FBUztRQUNoQixJQUFJLEVBQUUsUUFBUTtLQUNmLENBQUE7SUFFRCxPQUFPLE9BQU8sQ0FBQTtBQUNoQixDQUFDO0FBRUQsU0FBUyxrQkFBa0IsQ0FBQyxPQUczQjtJQUNDLE1BQU0sRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLEdBQUcsT0FBTyxJQUFJLEVBQUUsQ0FBQTtJQUVsRCxNQUFNLE9BQU8sR0FBbUM7UUFDOUMsVUFBVTtRQUNWLFFBQVEsRUFBRSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUU7UUFDN0IsV0FBVyxFQUFFLFlBQVk7WUFDdkIsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRTtZQUNwQixDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUU7UUFDdkMsZUFBZSxFQUFFLFlBQVk7WUFDM0IsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFO1lBQ3JDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUU7UUFDdEIsa0JBQWtCLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUU7UUFDdEQsa0JBQWtCLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsV0FBVyxFQUFFLEdBQUcsRUFBRTtRQUV4RSxVQUFVO1FBQ1Ysc0NBQXNDLEVBQUUsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFO1FBRTNELE9BQU87UUFDUCx3QkFBd0IsRUFBRSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUU7UUFDMUMsd0JBQXdCLEVBQUUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUU7UUFDOUQsd0JBQXdCLEVBQUUsVUFBVTtZQUNsQyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUU7WUFDdEMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFO1FBQ3hDLHdCQUF3QixFQUFFLFVBQVU7WUFDbEMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFO1lBQ3RDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRTtRQUN4Qyw0QkFBNEIsRUFBRSxVQUFVO1lBQ3RDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRTtZQUN0QyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUU7UUFFeEMsT0FBTztRQUNQLHdCQUF3QixFQUFFLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRTtRQUMxQyxpQkFBaUIsRUFBRSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRTtRQUNwRCwyQ0FBMkMsRUFBRTtZQUMzQyxJQUFJLEVBQUUsTUFBTTtZQUNaLE1BQU0sRUFBRSxhQUFhO1NBQ3RCO1FBQ0Qsb0NBQW9DLEVBQUUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUU7UUFDMUUsMENBQTBDLEVBQUUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFO1FBRTVELHdCQUF3QjtRQUN4QiwrQ0FBK0MsRUFBRSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUU7UUFDckUsK0RBQStELEVBQUU7WUFDL0QsSUFBSSxFQUFFLFVBQVU7U0FDakI7UUFDRCw2Q0FBNkMsRUFBRTtZQUM3QyxJQUFJLEVBQUUsVUFBVTtZQUNoQixNQUFNLEVBQUUsbUJBQW1CO1NBQzVCO1FBQ0Qsc0NBQXNDLEVBQUUsVUFBVTtZQUNoRCxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxnQkFBZ0IsRUFBRTtZQUNoRCxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxnQkFBZ0IsRUFBRTtRQUNsRCw2Q0FBNkMsRUFBRSxVQUFVO1lBQ3ZELENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLG1CQUFtQixFQUFFO1lBQ25ELENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLG1CQUFtQixFQUFFO1FBRXJELFNBQVM7UUFDVCxNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO1FBRTFCLFFBQVE7UUFDUixNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFO0tBQzFCLENBQUE7SUFFRCxPQUFPLE9BQU8sQ0FBQTtBQUNoQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBGaWVsZCwgU2NoZW1hIH0gZnJvbSBcIkBkcGtpdC9jb3JlXCJcbmltcG9ydCB7IGNvbCB9IGZyb20gXCJub2RlanMtcG9sYXJzXCJcbmltcG9ydCB7IGdldFBvbGFyc1NjaGVtYSB9IGZyb20gXCIuLi9zY2hlbWEvaW5kZXgudHNcIlxuaW1wb3J0IHR5cGUgeyBUYWJsZSB9IGZyb20gXCIuLi90YWJsZS9pbmRleC50c1wiXG5cbi8vIFRPRE86IFJldmlldyBkZWZhdWx0IHZhbHVlcyBiZWluZyB7ZmllbGRzOiBbXX0gdnMgdW5kZWZpbmVkXG5cbmV4cG9ydCB0eXBlIEluZmVyU2NoZW1hT3B0aW9ucyA9IHtcbiAgc2FtcGxlUm93cz86IG51bWJlclxuICBjb25maWRlbmNlPzogbnVtYmVyXG4gIGNvbW1hRGVjaW1hbD86IGJvb2xlYW5cbiAgbW9udGhGaXJzdD86IGJvb2xlYW5cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGluZmVyU2NoZW1hKHRhYmxlOiBUYWJsZSwgb3B0aW9ucz86IEluZmVyU2NoZW1hT3B0aW9ucykge1xuICBjb25zdCB7IHNhbXBsZVJvd3MgPSAxMDAsIGNvbmZpZGVuY2UgPSAwLjkgfSA9IG9wdGlvbnMgPz8ge31cbiAgY29uc3Qgc2NoZW1hOiBTY2hlbWEgPSB7XG4gICAgZmllbGRzOiBbXSxcbiAgfVxuXG4gIGNvbnN0IHR5cGVNYXBwaW5nID0gY3JlYXRlVHlwZU1hcHBpbmcoKVxuICBjb25zdCByZWdleE1hcHBpbmcgPSBjcmVhdGVSZWdleE1hcHBpbmcob3B0aW9ucylcblxuICBjb25zdCBzYW1wbGUgPSBhd2FpdCB0YWJsZS5oZWFkKHNhbXBsZVJvd3MpLmNvbGxlY3QoKVxuICBjb25zdCBwb2xhcnNTY2hlbWEgPSBnZXRQb2xhcnNTY2hlbWEoc2FtcGxlLnNjaGVtYSlcblxuICBjb25zdCBmYWlsdXJlVGhyZXNob2xkID1cbiAgICBzYW1wbGUuaGVpZ2h0IC0gTWF0aC5mbG9vcihzYW1wbGUuaGVpZ2h0ICogY29uZmlkZW5jZSkgfHwgMVxuXG4gIGZvciAoY29uc3QgcG9sYXJzRmllbGQgb2YgcG9sYXJzU2NoZW1hLmZpZWxkcykge1xuICAgIGNvbnN0IG5hbWUgPSBwb2xhcnNGaWVsZC5uYW1lXG4gICAgY29uc3QgdHlwZSA9IHR5cGVNYXBwaW5nW3BvbGFyc0ZpZWxkLnR5cGUudmFyaWFudF0gPz8gXCJhbnlcIlxuXG4gICAgbGV0IGZpZWxkID0geyBuYW1lLCB0eXBlIH1cblxuICAgIGlmICh0eXBlID09PSBcInN0cmluZ1wiKSB7XG4gICAgICBmb3IgKGNvbnN0IFtyZWdleCwgcGF0Y2hdIG9mIE9iamVjdC5lbnRyaWVzKHJlZ2V4TWFwcGluZykpIHtcbiAgICAgICAgY29uc3QgZmFpbHVyZXMgPSBzYW1wbGVcbiAgICAgICAgICAuZmlsdGVyKGNvbChuYW1lKS5zdHIuY29udGFpbnMocmVnZXgpLm5vdCgpKVxuICAgICAgICAgIC5oZWFkKGZhaWx1cmVUaHJlc2hvbGQpLmhlaWdodFxuICAgICAgICBpZiAoZmFpbHVyZXMgPCBmYWlsdXJlVGhyZXNob2xkKSB7XG4gICAgICAgICAgZmllbGQgPSB7IC4uLmZpZWxkLCAuLi5wYXRjaCB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHNjaGVtYS5maWVsZHMucHVzaChmaWVsZClcbiAgfVxuXG4gIHJldHVybiBzY2hlbWFcbn1cblxuZnVuY3Rpb24gY3JlYXRlVHlwZU1hcHBpbmcoKSB7XG4gIGNvbnN0IG1hcHBpbmc6IFJlY29yZDxzdHJpbmcsIEZpZWxkW1widHlwZVwiXT4gPSB7XG4gICAgQXJyYXk6IFwiYXJyYXlcIixcbiAgICBCb29sOiBcImJvb2xlYW5cIixcbiAgICBDYXRlZ29yaWNhbDogXCJzdHJpbmdcIixcbiAgICBEYXRlOiBcImRhdGVcIixcbiAgICBEYXRldGltZTogXCJkYXRldGltZVwiLFxuICAgIERlY2ltYWw6IFwibnVtYmVyXCIsXG4gICAgRmxvYXQzMjogXCJudW1iZXJcIixcbiAgICBGbG9hdDY0OiBcIm51bWJlclwiLFxuICAgIEludDE2OiBcImludGVnZXJcIixcbiAgICBJbnQzMjogXCJpbnRlZ2VyXCIsXG4gICAgSW50NjQ6IFwiaW50ZWdlclwiLFxuICAgIEludDg6IFwiaW50ZWdlclwiLFxuICAgIExpc3Q6IFwiYXJyYXlcIixcbiAgICBOdWxsOiBcImFueVwiLFxuICAgIE9iamVjdDogXCJvYmplY3RcIixcbiAgICBTdHJpbmc6IFwic3RyaW5nXCIsXG4gICAgU3RydWN0OiBcIm9iamVjdFwiLFxuICAgIFRpbWU6IFwidGltZVwiLFxuICAgIFVJbnQxNjogXCJpbnRlZ2VyXCIsXG4gICAgVUludDMyOiBcImludGVnZXJcIixcbiAgICBVSW50NjQ6IFwiaW50ZWdlclwiLFxuICAgIFVJbnQ4OiBcImludGVnZXJcIixcbiAgICBVdGY4OiBcInN0cmluZ1wiLFxuICB9XG5cbiAgcmV0dXJuIG1hcHBpbmdcbn1cblxuZnVuY3Rpb24gY3JlYXRlUmVnZXhNYXBwaW5nKG9wdGlvbnM/OiB7XG4gIGNvbW1hRGVjaW1hbD86IGJvb2xlYW5cbiAgbW9udGhGaXJzdD86IGJvb2xlYW5cbn0pIHtcbiAgY29uc3QgeyBjb21tYURlY2ltYWwsIG1vbnRoRmlyc3QgfSA9IG9wdGlvbnMgPz8ge31cblxuICBjb25zdCBtYXBwaW5nOiBSZWNvcmQ8c3RyaW5nLCBQYXJ0aWFsPEZpZWxkPj4gPSB7XG4gICAgLy8gTnVtZXJpY1xuICAgIFwiXlxcXFxkKyRcIjogeyB0eXBlOiBcImludGVnZXJcIiB9LFxuICAgIFwiXlssXFxcXGRdKyRcIjogY29tbWFEZWNpbWFsXG4gICAgICA/IHsgdHlwZTogXCJudW1iZXJcIiB9XG4gICAgICA6IHsgdHlwZTogXCJpbnRlZ2VyXCIsIGdyb3VwQ2hhcjogXCIsXCIgfSxcbiAgICBcIl5cXFxcZCtcXFxcLlxcXFxkKyRcIjogY29tbWFEZWNpbWFsXG4gICAgICA/IHsgdHlwZTogXCJpbnRlZ2VyXCIsIGdyb3VwQ2hhcjogXCIuXCIgfVxuICAgICAgOiB7IHR5cGU6IFwibnVtYmVyXCIgfSxcbiAgICBcIl5bLFxcXFxkXStcXFxcLlxcXFxkKyRcIjogeyB0eXBlOiBcIm51bWJlclwiLCBncm91cENoYXI6IFwiLFwiIH0sXG4gICAgXCJeWy5cXFxcZF0rXFxcXCxcXFxcZCskXCI6IHsgdHlwZTogXCJudW1iZXJcIiwgZ3JvdXBDaGFyOiBcIi5cIiwgZGVjaW1hbENoYXI6IFwiLFwiIH0sXG5cbiAgICAvLyBCb29sZWFuXG4gICAgXCJeKHRydWV8VHJ1ZXxUUlVFfGZhbHNlfEZhbHNlfEZBTFNFKSRcIjogeyB0eXBlOiBcImJvb2xlYW5cIiB9LFxuXG4gICAgLy8gRGF0ZVxuICAgIFwiXlxcXFxkezR9LVxcXFxkezJ9LVxcXFxkezJ9JFwiOiB7IHR5cGU6IFwiZGF0ZVwiIH0sXG4gICAgXCJeXFxcXGR7NH0vXFxcXGR7Mn0vXFxcXGR7Mn0kXCI6IHsgdHlwZTogXCJkYXRlXCIsIGZvcm1hdDogXCIlWS8lbS8lZFwiIH0sXG4gICAgXCJeXFxcXGR7Mn0vXFxcXGR7Mn0vXFxcXGR7NH0kXCI6IG1vbnRoRmlyc3RcbiAgICAgID8geyB0eXBlOiBcImRhdGVcIiwgZm9ybWF0OiBcIiVtLyVkLyVZXCIgfVxuICAgICAgOiB7IHR5cGU6IFwiZGF0ZVwiLCBmb3JtYXQ6IFwiJWQvJW0vJVlcIiB9LFxuICAgIFwiXlxcXFxkezJ9LVxcXFxkezJ9LVxcXFxkezR9JFwiOiBtb250aEZpcnN0XG4gICAgICA/IHsgdHlwZTogXCJkYXRlXCIsIGZvcm1hdDogXCIlbS0lZC0lWVwiIH1cbiAgICAgIDogeyB0eXBlOiBcImRhdGVcIiwgZm9ybWF0OiBcIiVkLSVtLSVZXCIgfSxcbiAgICBcIl5cXFxcZHsyfVxcXFwuXFxcXGR7Mn1cXFxcLlxcXFxkezR9JFwiOiBtb250aEZpcnN0XG4gICAgICA/IHsgdHlwZTogXCJkYXRlXCIsIGZvcm1hdDogXCIlbS4lZC4lWVwiIH1cbiAgICAgIDogeyB0eXBlOiBcImRhdGVcIiwgZm9ybWF0OiBcIiVkLiVtLiVZXCIgfSxcblxuICAgIC8vIFRpbWVcbiAgICBcIl5cXFxcZHsyfTpcXFxcZHsyfTpcXFxcZHsyfSRcIjogeyB0eXBlOiBcInRpbWVcIiB9LFxuICAgIFwiXlxcXFxkezJ9OlxcXFxkezJ9JFwiOiB7IHR5cGU6IFwidGltZVwiLCBmb3JtYXQ6IFwiJUg6JU1cIiB9LFxuICAgIFwiXlxcXFxkezEsMn06XFxcXGR7Mn06XFxcXGR7Mn1cXFxccyooYW18cG18QU18UE0pJFwiOiB7XG4gICAgICB0eXBlOiBcInRpbWVcIixcbiAgICAgIGZvcm1hdDogXCIlSTolTTolUyAlcFwiLFxuICAgIH0sXG4gICAgXCJeXFxcXGR7MSwyfTpcXFxcZHsyfVxcXFxzKihhbXxwbXxBTXxQTSkkXCI6IHsgdHlwZTogXCJ0aW1lXCIsIGZvcm1hdDogXCIlSTolTSAlcFwiIH0sXG4gICAgXCJeXFxcXGR7Mn06XFxcXGR7Mn06XFxcXGR7Mn1bKy1dXFxcXGR7Mn06P1xcXFxkezJ9JFwiOiB7IHR5cGU6IFwidGltZVwiIH0sXG5cbiAgICAvLyBEYXRldGltZSAtIElTTyBmb3JtYXRcbiAgICBcIl5cXFxcZHs0fS1cXFxcZHsyfS1cXFxcZHsyfVRcXFxcZHsyfTpcXFxcZHsyfTpcXFxcZHsyfVo/JFwiOiB7IHR5cGU6IFwiZGF0ZXRpbWVcIiB9LFxuICAgIFwiXlxcXFxkezR9LVxcXFxkezJ9LVxcXFxkezJ9VFxcXFxkezJ9OlxcXFxkezJ9OlxcXFxkezJ9WystXVxcXFxkezJ9Oj9cXFxcZHsyfSRcIjoge1xuICAgICAgdHlwZTogXCJkYXRldGltZVwiLFxuICAgIH0sXG4gICAgXCJeXFxcXGR7NH0tXFxcXGR7Mn0tXFxcXGR7Mn0gXFxcXGR7Mn06XFxcXGR7Mn06XFxcXGR7Mn0kXCI6IHtcbiAgICAgIHR5cGU6IFwiZGF0ZXRpbWVcIixcbiAgICAgIGZvcm1hdDogXCIlWS0lbS0lZCAlSDolTTolU1wiLFxuICAgIH0sXG4gICAgXCJeXFxcXGR7Mn0vXFxcXGR7Mn0vXFxcXGR7NH0gXFxcXGR7Mn06XFxcXGR7Mn0kXCI6IG1vbnRoRmlyc3RcbiAgICAgID8geyB0eXBlOiBcImRhdGV0aW1lXCIsIGZvcm1hdDogXCIlbS8lZC8lWSAlSDolTVwiIH1cbiAgICAgIDogeyB0eXBlOiBcImRhdGV0aW1lXCIsIGZvcm1hdDogXCIlZC8lbS8lWSAlSDolTVwiIH0sXG4gICAgXCJeXFxcXGR7Mn0vXFxcXGR7Mn0vXFxcXGR7NH0gXFxcXGR7Mn06XFxcXGR7Mn06XFxcXGR7Mn0kXCI6IG1vbnRoRmlyc3RcbiAgICAgID8geyB0eXBlOiBcImRhdGV0aW1lXCIsIGZvcm1hdDogXCIlbS8lZC8lWSAlSDolTTolU1wiIH1cbiAgICAgIDogeyB0eXBlOiBcImRhdGV0aW1lXCIsIGZvcm1hdDogXCIlZC8lbS8lWSAlSDolTTolU1wiIH0sXG5cbiAgICAvLyBPYmplY3RcbiAgICBcIl5cXFxce1wiOiB7IHR5cGU6IFwib2JqZWN0XCIgfSxcblxuICAgIC8vIEFycmF5XG4gICAgXCJeXFxcXFtcIjogeyB0eXBlOiBcImFycmF5XCIgfSxcbiAgfVxuXG4gIHJldHVybiBtYXBwaW5nXG59XG4iXX0=