@dpkit/core
Version:
Fast TypeScript data management framework built on top of the Data Package standard and Polars DataFrames
272 lines • 26.9 kB
JavaScript
import { relative } from "node:path";
import { describe, expect, it } from "vitest";
import { denormalizePath, getBasepath, getFilename, isRemotePath, normalizePath, } from "./path.js";
describe("isRemotePath", () => {
it.each([
{
description: "http URL",
path: "http://example.com/path/to/file.txt",
isRemote: true,
},
{
description: "https URL",
path: "https://example.com/path/to/file.txt",
isRemote: true,
},
{
description: "ftp URL",
path: "ftp://example.com/path/to/file.txt",
isRemote: true,
},
{
description: "file URL",
path: "file:///path/to/file.txt",
isRemote: true,
},
{
description: "absolute path",
path: "/path/to/file.txt",
isRemote: false,
},
{
description: "relative path",
path: "path/to/file.txt",
isRemote: false,
},
{
description: "current directory path",
path: "./file.txt",
isRemote: false,
},
{
description: "parent directory path",
path: "../file.txt",
isRemote: false,
},
{
description: "empty string",
path: "",
isRemote: false,
},
{
// new URL considers this to be a valid URL
description: "protocol without slashes",
path: "http:example.com",
isRemote: true,
},
])("$description", ({ path, isRemote }) => {
expect(isRemotePath(path)).toBe(isRemote);
});
});
describe("getFilename", () => {
it.each([
{
description: "simple filename",
path: "file.txt",
filename: "file.txt",
},
{
description: "directory path with filename",
path: "some/path/to/file.txt",
filename: "file.txt",
},
{
description: "remote HTTP URL",
path: "http://example.com/path/to/file.txt",
filename: "file.txt",
},
{
description: "remote HTTPS URL",
path: "https://example.com/path/to/file.txt",
filename: "file.txt",
},
{
description: "URL with query parameters",
path: "https://example.com/path/to/file.txt?query=param",
filename: "file.txt",
},
{
description: "URL with hash",
path: "https://example.com/path/to/file.txt#section",
filename: "file.txt",
},
{
description: "URL with query and hash",
path: "https://example.com/path/to/file.txt?query=param#section",
filename: "file.txt",
},
{
description: "URL with no filename",
path: "https://example.com/path/",
filename: undefined,
},
{
description: "local path with no filename",
path: "some/path/",
filename: undefined,
},
])("$description", ({ path, filename }) => {
expect(getFilename(path)).toEqual(filename);
});
});
describe("getBasepath", () => {
it.each([
{
description: "http URL with file",
path: "http://example.com/path/to/file.txt",
basepath: "http://example.com/path/to",
},
{
description: "https URL with file",
path: "https://example.com/path/to/file.txt",
basepath: "https://example.com/path/to",
},
{
description: "URL with query parameters",
path: "https://example.com/path/to/file.txt?query=param",
basepath: "https://example.com/path/to",
},
{
description: "URL with hash",
path: "https://example.com/path/to/file.txt#section",
basepath: "https://example.com/path/to",
},
{
description: "URL with no file",
path: "https://example.com/path/to/",
basepath: "https://example.com/path/to",
},
{
description: "URL with only domain",
path: "https://example.com",
basepath: "https://example.com",
},
{
description: "local file path",
path: "some/path/to/file.txt",
basepath: "some/path/to",
},
{
description: "local path with no file",
path: "some/path/to/",
basepath: "some/path",
},
{
description: "root level file",
path: "file.txt",
basepath: "",
},
])("$description", ({ path, basepath }) => {
expect(getBasepath(path)).toEqual(basepath);
});
});
describe("normalizePath", () => {
it.each([
{
description: "local path without basepath",
path: "path/to/file.txt",
basepath: undefined,
normalizedPath: "path/to/file.txt",
},
{
description: "local path with local basepath",
path: "file.txt",
basepath: "path/to",
normalizedPath: "path/to/file.txt",
},
{
description: "remote path",
path: "http://example.com/path/to/file.txt",
basepath: undefined,
normalizedPath: "http://example.com/path/to/file.txt",
},
{
description: "remote path with query string",
path: "http://example.com/path/to/file.txt?query=param",
basepath: undefined,
normalizedPath: "http://example.com/path/to/file.txt?query=param",
},
{
description: "local path with remote basepath",
path: "path/to/file.txt",
basepath: "http://example.com",
normalizedPath: "http://example.com/path/to/file.txt",
},
{
description: "local path with absolute basepath",
path: "file.txt",
basepath: "/absolute/path",
normalizedPath: relative(process.cwd(), "/absolute/path/file.txt"),
},
{
description: "path with empty basepath",
path: "path/to/file.txt",
basepath: "",
normalizedPath: "path/to/file.txt",
},
])("$description", ({ path, basepath, normalizedPath }) => {
expect(normalizePath(path, { basepath })).toEqual(normalizedPath);
});
it.each([
{
description: "absolute path",
path: "/absolute/path/to/file.txt",
basepath: undefined,
},
{
description: "local traversed path",
path: "../file.txt",
basepath: "/folder",
},
{
description: "remote traversed path",
path: "../file.txt",
basepath: "http://example.com/data",
},
])("$description -- throw", ({ path, basepath }) => {
expect(() => normalizePath(path, { basepath })).toThrow();
});
});
describe("denormalizePath", () => {
it.each([
{
description: "remote URL without basepath",
path: "http://example.com/path/to/file.txt",
basepath: undefined,
denormalizedPath: "http://example.com/path/to/file.txt",
},
{
description: "remote URL with basepath",
path: "http://example.com/path/to/file.txt",
basepath: "data",
denormalizedPath: "http://example.com/path/to/file.txt",
},
{
description: "local file in subfolder",
path: "/tmp/data/file.csv",
basepath: "/tmp",
denormalizedPath: "data/file.csv",
},
{
description: "local file in direct child folder",
path: "/tmp/file.csv",
basepath: "/tmp",
denormalizedPath: "file.csv",
},
{
description: "local file with deeply nested basepath",
path: "/tmp/data/nested/deep/file.csv",
basepath: "/tmp/data/nested",
denormalizedPath: "deep/file.csv",
},
{
description: "local file with multi-level basepath",
path: "/home/user/projects/data/file.csv",
basepath: "/home/user/projects",
denormalizedPath: "data/file.csv",
},
])("$description", ({ path, basepath, denormalizedPath }) => {
expect(denormalizePath(path, { basepath })).toEqual(denormalizedPath);
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF0aC5zcGVjLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vZ2VuZXJhbC9wYXRoLnNwZWMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFdBQVcsQ0FBQTtBQUNwQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsTUFBTSxRQUFRLENBQUE7QUFDN0MsT0FBTyxFQUNMLGVBQWUsRUFDZixXQUFXLEVBQ1gsV0FBVyxFQUNYLFlBQVksRUFDWixhQUFhLEdBQ2QsTUFBTSxXQUFXLENBQUE7QUFFbEIsUUFBUSxDQUFDLGNBQWMsRUFBRSxHQUFHLEVBQUU7SUFDNUIsRUFBRSxDQUFDLElBQUksQ0FBQztRQUNOO1lBQ0UsV0FBVyxFQUFFLFVBQVU7WUFDdkIsSUFBSSxFQUFFLHFDQUFxQztZQUMzQyxRQUFRLEVBQUUsSUFBSTtTQUNmO1FBQ0Q7WUFDRSxXQUFXLEVBQUUsV0FBVztZQUN4QixJQUFJLEVBQUUsc0NBQXNDO1lBQzVDLFFBQVEsRUFBRSxJQUFJO1NBQ2Y7UUFDRDtZQUNFLFdBQVcsRUFBRSxTQUFTO1lBQ3RCLElBQUksRUFBRSxvQ0FBb0M7WUFDMUMsUUFBUSxFQUFFLElBQUk7U0FDZjtRQUNEO1lBQ0UsV0FBVyxFQUFFLFVBQVU7WUFDdkIsSUFBSSxFQUFFLDBCQUEwQjtZQUNoQyxRQUFRLEVBQUUsSUFBSTtTQUNmO1FBQ0Q7WUFDRSxXQUFXLEVBQUUsZUFBZTtZQUM1QixJQUFJLEVBQUUsbUJBQW1CO1lBQ3pCLFFBQVEsRUFBRSxLQUFLO1NBQ2hCO1FBQ0Q7WUFDRSxXQUFXLEVBQUUsZUFBZTtZQUM1QixJQUFJLEVBQUUsa0JBQWtCO1lBQ3hCLFFBQVEsRUFBRSxLQUFLO1NBQ2hCO1FBQ0Q7WUFDRSxXQUFXLEVBQUUsd0JBQXdCO1lBQ3JDLElBQUksRUFBRSxZQUFZO1lBQ2xCLFFBQVEsRUFBRSxLQUFLO1NBQ2hCO1FBQ0Q7WUFDRSxXQUFXLEVBQUUs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QyxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFBO0lBQ3ZFLENBQUMsQ0FBQyxDQUFBO0FBQ0osQ0FBQyxDQUFDLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyByZWxhdGl2ZSB9IGZyb20gXCJub2RlOnBhdGhcIlxuaW1wb3J0IHsgZGVzY3JpYmUsIGV4cGVjdCwgaXQgfSBmcm9tIFwidml0ZXN0XCJcbmltcG9ydCB7XG4gIGRlbm9ybWFsaXplUGF0aCxcbiAgZ2V0QmFzZXBhdGgsXG4gIGdldEZpbGVuYW1lLFxuICBpc1JlbW90ZVBhdGgsXG4gIG5vcm1hbGl6ZVBhdGgsXG59IGZyb20gXCIuL3BhdGgudHNcIlxuXG5kZXNjcmliZShcImlzUmVtb3RlUGF0aFwiLCAoKSA9PiB7XG4gIGl0LmVhY2goW1xuICAgIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcImh0dHAgVVJMXCIsXG4gICAgICBwYXRoOiBcImh0dHA6Ly9leGFtcGxlLmNvbS9wYXRoL3RvL2ZpbGUudHh0XCIsXG4gICAgICBpc1JlbW90ZTogdHJ1ZSxcbiAgICB9LFxuICAgIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcImh0dHBzIFVSTFwiLFxuICAgICAgcGF0aDogXCJodHRwczovL2V4YW1wbGUuY29tL3BhdGgvdG8vZmlsZS50eHRcIixcbiAgICAgIGlzUmVtb3RlOiB0cnVlLFxuICAgIH0sXG4gICAge1xuICAgICAgZGVzY3JpcHRpb246IFwiZnRwIFVSTFwiLFxuICAgICAgcGF0aDogXCJmdHA6Ly9leGFtcGxlLmNvbS9wYXRoL3RvL2ZpbGUudHh0XCIsXG4gICAgICBpc1JlbW90ZTogdHJ1ZSxcbiAgICB9LFxuICAgIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcImZpbGUgVVJMXCIsXG4gICAgICBwYXRoOiBcImZpbGU6Ly8vcGF0aC90by9maWxlLnR4dFwiLFxuICAgICAgaXNSZW1vdGU6IHRydWUsXG4gICAgfSxcbiAgICB7XG4gICAgICBkZXNjcmlwdGlvbjogXCJhYnNvbHV0ZSBwYXRoXCIsXG4gICAgICBwYXRoOiBcIi9wYXRoL3RvL2ZpbGUudHh0XCIsXG4gICAgICBpc1JlbW90ZTogZmFsc2UsXG4gICAgfSxcbiAgICB7XG4gICAgICBkZXNjcmlwdGlvbjogXCJyZWxhdGl2ZSBwYXRoXCIsXG4gICAgICBwYXRoOiBcInBhdGgvdG8vZmlsZS50eHRcIixcbiAgICAgIGlzUmVtb3RlOiBmYWxzZSxcbiAgICB9LFxuICAgIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcImN1cnJlbnQgZGlyZWN0b3J5IHBhdGhcIixcbiAgICAgIHBhdGg6IFwiLi9maWxlLnR4dFwiLFxuICAgICAgaXNSZW1vdGU6IGZhbHNlLFxuICAgIH0sXG4gICAge1xuICAgICAgZGVzY3JpcHRpb246IFwicGFyZW50IGRpcmVjdG9yeSBwYXRoXCIsXG4gICAgICBwYXRoOiBcIi4uL2ZpbGUudHh0XCIsXG4gICAgICBpc1JlbW90ZTogZmFsc2UsXG4gICAgfSxcbiAgICB7XG4gICAgICBkZXNjcmlwdGlvbjogXCJlbXB0eSBzdHJpbmdcIixcbiAgICAgIHBhdGg6IFwiXCIsXG4gICAgICBpc1JlbW90ZTogZmFsc2UsXG4gICAgfSxcbiAgICB7XG4gICAgICAvLyBuZXcgVVJMIGNvbnNpZGVycyB0aGlzIHRvIGJlIGEgdmFsaWQgVVJMXG4gICAgICBkZXNjcmlwdGlvbjogXCJwcm90b2NvbCB3aXRob3V0IHNsYXNoZXNcIixcbiAgICAgIHBhdGg6IFwiaHR0cDpleGFtcGxlLmNvbVwiLFxuICAgICAgaXNSZW1vdGU6IHRydWUsXG4gICAgfSxcbiAgXSkoXCIkZGVzY3JpcHRpb25cIiwgKHsgcGF0aCwgaXNSZW1vdGUgfSkgPT4ge1xuICAgIGV4cGVjdChpc1JlbW90ZVBhdGgocGF0aCkpLnRvQmUoaXNSZW1vdGUpXG4gIH0pXG59KVxuXG5kZXNjcmliZShcImdldEZpbGVuYW1lXCIsICgpID0+IHtcbiAgaXQuZWFjaChbXG4gICAge1xuICAgICAgZGVzY3JpcHRpb246IFwic2ltcGxlIGZpbGVuYW1lXCIsXG4gICAgICBwYXRoOiBcImZpbGUudHh0XCIsXG4gICAgICBmaWxlbmFtZTogXCJmaWxlLnR4dFwiLFxuICAgIH0sXG4gICAge1xuICAgICAgZGVzY3JpcHRpb246IFwiZGlyZWN0b3J5IHBhdGggd2l0aCBmaWxlbmFtZVwiLFxuICAgICAgcGF0aDogXCJzb21lL3BhdGgvdG8vZmlsZS50eHRcIixcbiAgICAgIGZpbGVuYW1lOiBcImZpbGUudHh0XCIsXG4gICAgfSxcbiAgICB7XG4gICAgICBkZXNjcmlwdGlvbjogXCJyZW1vdGUgSFRUUCBVUkxcIixcbiAgICAgIHBhdGg6IFwiaHR0cDovL2V4YW1wbGUuY29tL3BhdGgvdG8vZmlsZS50eHRcIixcbiAgICAgIGZpbGVuYW1lOiBcImZpbGUudHh0XCIsXG4gICAgfSxcbiAgICB7XG4gICAgICBkZXNjcmlwdGlvbjogXCJyZW1vdGUgSFRUUFMgVVJMXCIsXG4gICAgICBwYXRoOiBcImh0dHBzOi8vZXhhbXBsZS5jb20vcGF0aC90by9maWxlLnR4dFwiLFxuICAgICAgZmlsZW5hbWU6IFwiZmlsZS50eHRcIixcbiAgICB9LFxuICAgIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcIlVSTCB3aXRoIHF1ZXJ5IHBhcmFtZXRlcnNcIixcbiAgICAgIHBhdGg6IFwiaHR0cHM6Ly9leGFtcGxlLmNvbS9wYXRoL3RvL2ZpbGUudHh0P3F1ZXJ5PXBhcmFtXCIsXG4gICAgICBmaWxlbmFtZTogXCJmaWxlLnR4dFwiLFxuICAgIH0sXG4gICAge1xuICAgICAgZGVzY3JpcHRpb246IFwiVVJMIHdpdGggaGFzaFwiLFxuICAgICAgcGF0aDogXCJodHRwczovL2V4YW1wbGUuY29tL3BhdGgvdG8vZmlsZS50eHQjc2VjdGlvblwiLFxuICAgICAgZmlsZW5hbWU6IFwiZmlsZS50eHRcIixcbiAgICB9LFxuICAgIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcIlVSTCB3aXRoIHF1ZXJ5IGFuZCBoYXNoXCIsXG4gICAgICBwYXRoOiBcImh0dHBzOi8vZXhhbXBsZS5jb20vcGF0aC90by9maWxlLnR4dD9xdWVyeT1wYXJhbSNzZWN0aW9uXCIsXG4gICAgICBmaWxlbmFtZTogXCJmaWxlLnR4dFwiLFxuICAgIH0sXG4gICAge1xuICAgICAgZGVzY3JpcHRpb246IFwiVVJMIHdpdGggbm8gZmlsZW5hbWVcIixcbiAgICAgIHBhdGg6IFwiaHR0cHM6Ly9leGFtcGxlLmNvbS9wYXRoL1wiLFxuICAgICAgZmlsZW5hbWU6IHVuZGVmaW5lZCxcbiAgICB9LFxuICAgIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcImxvY2FsIHBhdGggd2l0aCBubyBmaWxlbmFtZVwiLFxuICAgICAgcGF0aDogXCJzb21lL3BhdGgvXCIsXG4gICAgICBmaWxlbmFtZTogdW5kZWZpbmVkLFxuICAgIH0sXG4gIF0pKFwiJGRlc2NyaXB0aW9uXCIsICh7IHBhdGgsIGZpbGVuYW1lIH0pID0+IHtcbiAgICBleHBlY3QoZ2V0RmlsZW5hbWUocGF0aCkpLnRvRXF1YWwoZmlsZW5hbWUpXG4gIH0pXG59KVxuXG5kZXNjcmliZShcImdldEJhc2VwYXRoXCIsICgpID0+IHtcbiAgaXQuZWFjaChbXG4gICAge1xuICAgICAgZGVzY3JpcHRpb246IFwiaHR0cCBVUkwgd2l0aCBmaWxlXCIsXG4gICAgICBwYXRoOiBcImh0dHA6Ly9leGFtcGxlLmNvbS9wYXRoL3RvL2ZpbGUudHh0XCIsXG4gICAgICBiYXNlcGF0aDogXCJodHRwOi8vZXhhbXBsZS5jb20vcGF0aC90b1wiLFxuICAgIH0sXG4gICAge1xuICAgICAgZGVzY3JpcHRpb246IFwiaHR0cHMgVVJMIHdpdGggZmlsZVwiLFxuICAgICAgcGF0aDogXCJodHRwczovL2V4YW1wbGUuY29tL3BhdGgvdG8vZmlsZS50eHRcIixcbiAgICAgIGJhc2VwYXRoOiBcImh0dHBzOi8vZXhhbXBsZS5jb20vcGF0aC90b1wiLFxuICAgIH0sXG4gICAge1xuICAgICAgZGVzY3JpcHRpb246IFwiVVJMIHdpdGggcXVlcnkgcGFyYW1ldGVyc1wiLFxuICAgICAgcGF0aDogXCJodHRwczovL2V4YW1wbGUuY29tL3BhdGgvdG8vZmlsZS50eHQ/cXVlcnk9cGFyYW1cIixcbiAgICAgIGJhc2VwYXRoOiBcImh0dHBzOi8vZXhhbXBsZS5jb20vcGF0aC90b1wiLFxuICAgIH0sXG4gICAge1xuICAgICAgZGVzY3JpcHRpb246IFwiVVJMIHdpdGggaGFzaFwiLFxuICAgICAgcGF0aDogXCJodHRwczovL2V4YW1wbGUuY29tL3BhdGgvdG8vZmlsZS50eHQjc2VjdGlvblwiLFxuICAgICAgYmFzZXBhdGg6IFwiaHR0cHM6Ly9leGFtcGxlLmNvbS9wYXRoL3RvXCIsXG4gICAgfSxcbiAgICB7XG4gICAgICBkZXNjcmlwdGlvbjogXCJVUkwgd2l0aCBubyBmaWxlXCIsXG4gICAgICBwYXRoOiBcImh0dHBzOi8vZXhhbXBsZS5jb20vcGF0aC90by9cIixcbiAgICAgIGJhc2VwYXRoOiBcImh0dHBzOi8vZXhhbXBsZS5jb20vcGF0aC90b1wiLFxuICAgIH0sXG4gICAge1xuICAgICAgZGVzY3JpcHRpb246IFwiVVJMIHdpdGggb25seSBkb21haW5cIixcbiAgICAgIHBhdGg6IFwiaHR0cHM6Ly9leGFtcGxlLmNvbVwiLFxuICAgICAgYmFzZXBhdGg6IFwiaHR0cHM6Ly9leGFtcGxlLmNvbVwiLFxuICAgIH0sXG4gICAge1xuICAgICAgZGVzY3JpcHRpb246IFwibG9jYWwgZmlsZSBwYXRoXCIsXG4gICAgICBwYXRoOiBcInNvbWUvcGF0aC90by9maWxlLnR4dFwiLFxuICAgICAgYmFzZXBhdGg6IFwic29tZS9wYXRoL3RvXCIsXG4gICAgfSxcbiAgICB7XG4gICAgICBkZXNjcmlwdGlvbjogXCJsb2NhbCBwYXRoIHdpdGggbm8gZmlsZVwiLFxuICAgICAgcGF0aDogXCJzb21lL3BhdGgvdG8vXCIsXG4gICAgICBiYXNlcGF0aDogXCJzb21lL3BhdGhcIixcbiAgICB9LFxuICAgIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcInJvb3QgbGV2ZWwgZmlsZVwiLFxuICAgICAgcGF0aDogXCJmaWxlLnR4dFwiLFxuICAgICAgYmFzZXBhdGg6IFwiXCIsXG4gICAgfSxcbiAgXSkoXCIkZGVzY3JpcHRpb25cIiwgKHsgcGF0aCwgYmFzZXBhdGggfSkgPT4ge1xuICAgIGV4cGVjdChnZXRCYXNlcGF0aChwYXRoKSkudG9FcXVhbChiYXNlcGF0aClcbiAgfSlcbn0pXG5cbmRlc2NyaWJlKFwibm9ybWFsaXplUGF0aFwiLCAoKSA9PiB7XG4gIGl0LmVhY2goW1xuICAgIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcImxvY2FsIHBhdGggd2l0aG91dCBiYXNlcGF0aFwiLFxuICAgICAgcGF0aDogXCJwYXRoL3RvL2ZpbGUudHh0XCIsXG4gICAgICBiYXNlcGF0aDogdW5kZWZpbmVkLFxuICAgICAgbm9ybWFsaXplZFBhdGg6IFwicGF0aC90by9maWxlLnR4dFwiLFxuICAgIH0sXG4gICAge1xuICAgICAgZGVzY3JpcHRpb246IFwibG9jYWwgcGF0aCB3aXRoIGxvY2FsIGJhc2VwYXRoXCIsXG4gICAgICBwYXRoOiBcImZpbGUudHh0XCIsXG4gICAgICBiYXNlcGF0aDogXCJwYXRoL3RvXCIsXG4gICAgICBub3JtYWxpemVkUGF0aDogXCJwYXRoL3RvL2ZpbGUudHh0XCIsXG4gICAgfSxcbiAgICB7XG4gICAgICBkZXNjcmlwdGlvbjogXCJyZW1vdGUgcGF0aFwiLFxuICAgICAgcGF0aDogXCJodHRwOi8vZXhhbXBsZS5jb20vcGF0aC90by9maWxlLnR4dFwiLFxuICAgICAgYmFzZXBhdGg6IHVuZGVmaW5lZCxcbiAgICAgIG5vcm1hbGl6ZWRQYXRoOiBcImh0dHA6Ly9leGFtcGxlLmNvbS9wYXRoL3RvL2ZpbGUudHh0XCIsXG4gICAgfSxcbiAgICB7XG4gICAgICBkZXNjcmlwdGlvbjogXCJyZW1vdGUgcGF0aCB3aXRoIHF1ZXJ5IHN0cmluZ1wiLFxuICAgICAgcGF0aDogXCJodHRwOi8vZXhhbXBsZS5jb20vcGF0aC90by9maWxlLnR4dD9xdWVyeT1wYXJhbVwiLFxuICAgICAgYmFzZXBhdGg6IHVuZGVmaW5lZCxcbiAgICAgIG5vcm1hbGl6ZWRQYXRoOiBcImh0dHA6Ly9leGFtcGxlLmNvbS9wYXRoL3RvL2ZpbGUudHh0P3F1ZXJ5PXBhcmFtXCIsXG4gICAgfSxcbiAgICB7XG4gICAgICBkZXNjcmlwdGlvbjogXCJsb2NhbCBwYXRoIHdpdGggcmVtb3RlIGJhc2VwYXRoXCIsXG4gICAgICBwYXRoOiBcInBhdGgvdG8vZmlsZS50eHRcIixcbiAgICAgIGJhc2VwYXRoOiBcImh0dHA6Ly9leGFtcGxlLmNvbVwiLFxuICAgICAgbm9ybWFsaXplZFBhdGg6IFwiaHR0cDovL2V4YW1wbGUuY29tL3BhdGgvdG8vZmlsZS50eHRcIixcbiAgICB9LFxuICAgIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcImxvY2FsIHBhdGggd2l0aCBhYnNvbHV0ZSBiYXNlcGF0aFwiLFxuICAgICAgcGF0aDogXCJmaWxlLnR4dFwiLFxuICAgICAgYmFzZXBhdGg6IFwiL2Fic29sdXRlL3BhdGhcIixcbiAgICAgIG5vcm1hbGl6ZWRQYXRoOiByZWxhdGl2ZShwcm9jZXNzLmN3ZCgpLCBcIi9hYnNvbHV0ZS9wYXRoL2ZpbGUudHh0XCIpLFxuICAgIH0sXG4gICAge1xuICAgICAgZGVzY3JpcHRpb246IFwicGF0aCB3aXRoIGVtcHR5IGJhc2VwYXRoXCIsXG4gICAgICBwYXRoOiBcInBhdGgvdG8vZmlsZS50eHRcIixcbiAgICAgIGJhc2VwYXRoOiBcIlwiLFxuICAgICAgbm9ybWFsaXplZFBhdGg6IFwicGF0aC90by9maWxlLnR4dFwiLFxuICAgIH0sXG4gIF0pKFwiJGRlc2NyaXB0aW9uXCIsICh7IHBhdGgsIGJhc2VwYXRoLCBub3JtYWxpemVkUGF0aCB9KSA9PiB7XG4gICAgZXhwZWN0KG5vcm1hbGl6ZVBhdGgocGF0aCwgeyBiYXNlcGF0aCB9KSkudG9FcXVhbChub3JtYWxpemVkUGF0aClcbiAgfSlcblxuICBpdC5lYWNoKFtcbiAgICB7XG4gICAgICBkZXNjcmlwdGlvbjogXCJhYnNvbHV0ZSBwYXRoXCIsXG4gICAgICBwYXRoOiBcIi9hYnNvbHV0ZS9wYXRoL3RvL2ZpbGUudHh0XCIsXG4gICAgICBiYXNlcGF0aDogdW5kZWZpbmVkLFxuICAgIH0sXG4gICAge1xuICAgICAgZGVzY3JpcHRpb246IFwibG9jYWwgdHJhdmVyc2VkIHBhdGhcIixcbiAgICAgIHBhdGg6IFwiLi4vZmlsZS50eHRcIixcbiAgICAgIGJhc2VwYXRoOiBcIi9mb2xkZXJcIixcbiAgICB9LFxuICAgIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcInJlbW90ZSB0cmF2ZXJzZWQgcGF0aFwiLFxuICAgICAgcGF0aDogXCIuLi9maWxlLnR4dFwiLFxuICAgICAgYmFzZXBhdGg6IFwiaHR0cDovL2V4YW1wbGUuY29tL2RhdGFcIixcbiAgICB9LFxuICBdKShcIiRkZXNjcmlwdGlvbiAtLSB0aHJvd1wiLCAoeyBwYXRoLCBiYXNlcGF0aCB9KSA9PiB7XG4gICAgZXhwZWN0KCgpID0+IG5vcm1hbGl6ZVBhdGgocGF0aCwgeyBiYXNlcGF0aCB9KSkudG9UaHJvdygpXG4gIH0pXG59KVxuXG5kZXNjcmliZShcImRlbm9ybWFsaXplUGF0aFwiLCAoKSA9PiB7XG4gIGl0LmVhY2goW1xuICAgIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcInJlbW90ZSBVUkwgd2l0aG91dCBiYXNlcGF0aFwiLFxuICAgICAgcGF0aDogXCJodHRwOi8vZXhhbXBsZS5jb20vcGF0aC90by9maWxlLnR4dFwiLFxuICAgICAgYmFzZXBhdGg6IHVuZGVmaW5lZCxcbiAgICAgIGRlbm9ybWFsaXplZFBhdGg6IFwiaHR0cDovL2V4YW1wbGUuY29tL3BhdGgvdG8vZmlsZS50eHRcIixcbiAgICB9LFxuICAgIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcInJlbW90ZSBVUkwgd2l0aCBiYXNlcGF0aFwiLFxuICAgICAgcGF0aDogXCJodHRwOi8vZXhhbXBsZS5jb20vcGF0aC90by9maWxlLnR4dFwiLFxuICAgICAgYmFzZXBhdGg6IFwiZGF0YVwiLFxuICAgICAgZGVub3JtYWxpemVkUGF0aDogXCJodHRwOi8vZXhhbXBsZS5jb20vcGF0aC90by9maWxlLnR4dFwiLFxuICAgIH0sXG4gICAge1xuICAgICAgZGVzY3JpcHRpb246IFwibG9jYWwgZmlsZSBpbiBzdWJmb2xkZXJcIixcbiAgICAgIHBhdGg6IFwiL3RtcC9kYXRhL2ZpbGUuY3N2XCIsXG4gICAgICBiYXNlcGF0aDogXCIvdG1wXCIsXG4gICAgICBkZW5vcm1hbGl6ZWRQYXRoOiBcImRhdGEvZmlsZS5jc3ZcIixcbiAgICB9LFxuICAgIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcImxvY2FsIGZpbGUgaW4gZGlyZWN0IGNoaWxkIGZvbGRlclwiLFxuICAgICAgcGF0aDogXCIvdG1wL2ZpbGUuY3N2XCIsXG4gICAgICBiYXNlcGF0aDogXCIvdG1wXCIsXG4gICAgICBkZW5vcm1hbGl6ZWRQYXRoOiBcImZpbGUuY3N2XCIsXG4gICAgfSxcbiAgICB7XG4gICAgICBkZXNjcmlwdGlvbjogXCJsb2NhbCBmaWxlIHdpdGggZGVlcGx5IG5lc3RlZCBiYXNlcGF0aFwiLFxuICAgICAgcGF0aDogXCIvdG1wL2RhdGEvbmVzdGVkL2RlZXAvZmlsZS5jc3ZcIixcbiAgICAgIGJhc2VwYXRoOiBcIi90bXAvZGF0YS9uZXN0ZWRcIixcbiAgICAgIGRlbm9ybWFsaXplZFBhdGg6IFwiZGVlcC9maWxlLmNzdlwiLFxuICAgIH0sXG4gICAge1xuICAgICAgZGVzY3JpcHRpb246IFwibG9jYWwgZmlsZSB3aXRoIG11bHRpLWxldmVsIGJhc2VwYXRoXCIsXG4gICAgICBwYXRoOiBcIi9ob21lL3VzZXIvcHJvamVjdHMvZGF0YS9maWxlLmNzdlwiLFxuICAgICAgYmFzZXBhdGg6IFwiL2hvbWUvdXNlci9wcm9qZWN0c1wiLFxuICAgICAgZGVub3JtYWxpemVkUGF0aDogXCJkYXRhL2ZpbGUuY3N2XCIsXG4gICAgfSxcbiAgXSkoXCIkZGVzY3JpcHRpb25cIiwgKHsgcGF0aCwgYmFzZXBhdGgsIGRlbm9ybWFsaXplZFBhdGggfSkgPT4ge1xuICAgIGV4cGVjdChkZW5vcm1hbGl6ZVBhdGgocGF0aCwgeyBiYXNlcGF0aCB9KSkudG9FcXVhbChkZW5vcm1hbGl6ZWRQYXRoKVxuICB9KVxufSlcbiJdfQ==