kwikid-camera
Version:
KwikID's Camera Component
241 lines • 32.6 kB
JavaScript
import { __awaiter } from "tslib";
import { isEmptyValue, isNotEmptyValue } from "kwikid-toolkit";
// TOOLKIT
export function flipImageHorizontally(base64Image) {
// Create an HTML image element
const img = new Image();
img.src = base64Image;
// Create a canvas element
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
// Set the canvas dimensions to match the image
canvas.width = img.width;
canvas.height = img.height;
// Draw the image on the canvas, flipped horizontally
ctx.scale(-1, 1); // Flip horizontally
ctx.drawImage(img, -canvas.width, 0, canvas.width, canvas.height);
// Convert the canvas content to a base64 string
const flippedBase64 = canvas.toDataURL();
return flippedBase64;
}
// TOOLKIT
export function getDevicesList() {
return __awaiter(this, void 0, void 0, function* () {
const videoDevices = [];
yield navigator.mediaDevices.enumerateDevices().then((devices) => {
for (const device of devices) {
if (device.kind === "videoinput") {
videoDevices.push(device);
}
}
});
return videoDevices;
});
}
// TOOLKIT
export function getDeviceId(activeDeviceId) {
return __awaiter(this, void 0, void 0, function* () {
let deviceId = activeDeviceId;
const videoDevices = [];
yield navigator.mediaDevices.enumerateDevices().then((devices) => {
for (const device of devices) {
if (device.kind === "videoinput") {
videoDevices.push(device);
}
}
});
if (videoDevices.length === 1 || isEmptyValue(activeDeviceId)) {
deviceId = videoDevices[0].deviceId;
}
else {
const filteredVideoDevice = videoDevices.filter((videoDevice) => {
return videoDevice.deviceId !== activeDeviceId;
})[0];
deviceId = filteredVideoDevice.deviceId;
}
return deviceId;
});
}
// TOOLKIT
export function getImageFromBase64(base64String) {
return new Promise((resolve, reject) => {
const image = new Image();
image.onload = () => {
resolve(image);
};
image.onerror = (error) => {
reject(error);
};
image.src = base64String;
});
}
// TOOLKIT
export function getBase64FromImage(image) {
return new Promise((resolve, reject) => {
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
canvas.width = image.width;
canvas.height = image.height;
context.drawImage(image, 0, 0, image.width, image.height);
try {
const base64String = canvas.toDataURL("image/png");
resolve(base64String);
}
catch (error) {
reject(error);
}
});
}
// TOOLKIT
export function getBase64FromImageFile(imageFile) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => {
const base64String = reader.result;
resolve(base64String); // Resolve the Promise with the base64 string
};
reader.onerror = (error) => {
reject(error); // Reject the Promise in case of an error
};
reader.readAsDataURL(imageFile);
});
}
// TOOLKIT
export function getScaledImageFromVideo(video, flipped) {
return __awaiter(this, void 0, void 0, function* () {
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
const cameraWidth = video.videoWidth;
const cameraHeight = video.videoHeight;
const visibleWidth = video.clientWidth;
const visibleHeight = video.clientHeight;
const cameraRatio = cameraWidth / cameraHeight;
const visibleRatio = visibleWidth / visibleHeight;
let scaledWidth;
let scaledHeight;
if (cameraRatio >= visibleRatio) {
// Scale to Visible Height
const heightRatio = visibleHeight / cameraHeight;
scaledWidth = cameraWidth * heightRatio;
scaledHeight = cameraHeight * heightRatio;
}
else {
// Scale to Visible Width
const widthRatio = visibleWidth / cameraWidth;
scaledWidth = cameraWidth * widthRatio;
scaledHeight = cameraHeight * widthRatio;
}
canvas.width = scaledWidth;
canvas.height = scaledHeight;
if (flipped) {
context.translate(canvas.width, 0);
context.scale(-1, 1);
}
context.drawImage(video, 0, 0, cameraWidth, cameraHeight, 0, 0, scaledWidth, scaledHeight);
// Get the image data from the canvas as a base64-encoded string
const imageBase64 = canvas.toDataURL("image/png");
const image = (yield getImageFromBase64(imageBase64));
return { image, imageBase64 };
});
}
// TOOLKIT
export function getCroppedImage(image, requiredWidth, requiredHeight) {
return __awaiter(this, void 0, void 0, function* () {
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
const sx = (image.width - requiredWidth) / 2;
const sy = (image.height - requiredHeight) / 2;
const sWidth = requiredWidth;
const sHeight = requiredHeight;
const dx = 0;
const dy = 0;
const dWidth = requiredWidth;
const dHeight = requiredHeight;
canvas.width = dWidth;
canvas.height = dHeight;
context.save();
context.translate(0, 0);
context.scale(1, 1);
context.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
context.restore();
const croppedImageBase64 = canvas.toDataURL("image/png");
const croppedImage = (yield getImageFromBase64(croppedImageBase64));
return { image: croppedImage, imageBase64: croppedImageBase64 };
});
}
// TOOLKIT
export function getCroppedImageFromMask(image, leftShift, topShift, requiredWidth, requiredHeight) {
return __awaiter(this, void 0, void 0, function* () {
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
const sx = leftShift;
const sy = topShift;
const sWidth = requiredWidth;
const sHeight = requiredHeight;
const dx = 0;
const dy = 0;
const dWidth = requiredWidth;
const dHeight = requiredHeight;
canvas.width = dWidth;
canvas.height = dHeight;
context.save();
context.translate(0, 0);
context.scale(1, 1);
context.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
context.restore();
const croppedImageBase64 = canvas.toDataURL("image/png");
const croppedImage = (yield getImageFromBase64(croppedImageBase64));
return { image: croppedImage, imageBase64: croppedImageBase64 };
});
}
export function getCorrectImageFormat(image) {
if (isEmptyValue(image)) {
return "";
}
if (Array.isArray(image)) {
return image.find((img) => typeof img === "string" && img.length !== 0);
}
if (typeof image === "string") {
return image;
}
return "";
}
// TOOLKIT
export function getWatermarkedImage(image, data) {
return __awaiter(this, void 0, void 0, function* () {
if (isEmptyValue(image)) {
throw new Error("No image provided for watermarking!");
}
if (isEmptyValue(data)) {
return {
image,
imageBase64: yield getBase64FromImage(image),
errorMessage: "No data provided for watermarking!"
};
}
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
canvas.width = image.width;
canvas.height = image.height;
context.drawImage(image, 0, 0);
context.font = "12px Arial";
context.textAlign = "left";
context.textBaseline = "top";
context.fillStyle = "#a2a2a2c7";
const longestKey = Object.keys(data).reduce((a, b) => data[a].toString().length > data[b].toString().length ? a : b);
const rectangleWidth = context.measureText(data[longestKey]).width;
context.fillRect(10, 10, rectangleWidth + 95, 70);
context.fillStyle = "yellow";
let yIndex = 20;
for (const key in data) {
if (isNotEmptyValue(key)) {
context.fillText(`${key.split("_").join(" ").toLocaleUpperCase()}: ${data[key]}`, 20, yIndex);
yIndex += 20;
}
}
const watermarkedImageBase64 = canvas.toDataURL("image/png");
const watermarkedImage = (yield getImageFromBase64(watermarkedImageBase64));
return { image: watermarkedImage, imageBase64: watermarkedImageBase64 };
});
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia3dpa2lkLWNhbWVyYS12aWV3LmhlbHBlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2t3aWtpZC1jYW1lcmEvc3JjL2xpYi9jb21wb25lbnRzL2t3aWtpZC1jYW1lcmEtdmlldy9rd2lraWQtY2FtZXJhLXZpZXcuaGVscGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLGVBQWUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRS9ELFVBQVU7QUFDVixNQUFNLFVBQVUscUJBQXFCLENBQUMsV0FBbUI7SUFDdkQsK0JBQStCO0lBQy9CLE1BQU0sR0FBRyxHQUFHLElBQUksS0FBSyxFQUFFLENBQUM7SUFDeEIsR0FBRyxDQUFDLEdBQUcsR0FBRyxXQUFXLENBQUM7SUFFdEIsMEJBQTBCO0lBQzFCLE1BQU0sTUFBTSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDaEQsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUVwQywrQ0FBK0M7SUFDL0MsTUFBTSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDO0lBQ3pCLE1BQU0sQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQztJQUUzQixxREFBcUQ7SUFDckQsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLG9CQUFvQjtJQUN0QyxHQUFHLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBRWxFLGdEQUFnRDtJQUNoRCxNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUM7SUFFekMsT0FBTyxhQUFhLENBQUM7QUFDdkIsQ0FBQztBQUVELFVBQVU7QUFDVixNQUFNLFVBQWdCLGNBQWM7O1FBQ2xDLE1BQU0sWUFBWSxHQUFVLEVBQUUsQ0FBQztRQUUvQixNQUFNLFNBQVMsQ0FBQyxZQUFZLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUMvRCxLQUFLLE1BQU0sTUFBTSxJQUFJLE9BQU8sRUFBRTtnQkFDNUIsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLFlBQVksRUFBRTtvQkFDaEMsWUFBWSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztpQkFDM0I7YUFDRjtRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxZQUFZLENBQUM7SUFDdEIsQ0FBQztDQUFBO0FBRUQsVUFBVTtBQUNWLE1BQU0sVUFBZ0IsV0FBVyxDQUFDLGNBQXNCOztRQUN0RCxJQUFJLFFBQVEsR0FBVyxjQUFjLENBQUM7UUFDdEMsTUFBTSxZQUFZLEdBQVUsRUFBRSxDQUFDO1FBRS9CLE1BQU0sU0FBUyxDQUFDLFlBQVksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQy9ELEtBQUssTUFBTSxNQUFNLElBQUksT0FBTyxFQUFFO2dCQUM1QixJQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUssWUFBWSxFQUFFO29CQUNoQyxZQUFZLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2lCQUMzQjthQUNGO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLFlBQVksQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLFlBQVksQ0FBQyxjQUFjLENBQUMsRUFBRTtZQUM3RCxRQUFRLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztTQUNyQzthQUFNO1lBQ0wsTUFBTSxtQkFBbUIsR0FBRyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUMsV0FBVyxFQUFFLEVBQUU7Z0JBQzlELE9BQU8sV0FBVyxDQUFDLFFBQVEsS0FBSyxjQUFjLENBQUM7WUFDakQsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFTixRQUFRLEdBQUcsbUJBQW1CLENBQUMsUUFBUSxDQUFDO1NBQ3pDO1FBRUQsT0FBTyxRQUFRLENBQUM7SUFDbEIsQ0FBQztDQUFBO0FBRUQsVUFBVTtBQUNWLE1BQU0sVUFBVSxrQkFBa0IsQ0FDaEMsWUFBb0I7SUFFcEIsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtRQUNyQyxNQUFNLEtBQUssR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFDO1FBRTFCLEtBQUssQ0FBQyxNQUFNLEdBQUcsR0FBRyxFQUFFO1lBQ2xCLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNqQixDQUFDLENBQUM7UUFFRixLQUFLLENBQUMsT0FBTyxHQUFHLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDeEIsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2hCLENBQUMsQ0FBQztRQUVGLEtBQUssQ0FBQyxHQUFHLEdBQUcsWUFBWSxDQUFDO0lBQzNCLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELFVBQVU7QUFDVixNQUFNLFVBQVUsa0JBQWtCLENBQUMsS0FBdUI7SUFDeEQsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtRQUNyQyxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ2hELE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFeEMsTUFBTSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDO1FBQzNCLE1BQU0sQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQztRQUU3QixPQUFPLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRTFELElBQUk7WUFDRixNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQ25ELE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQztTQUN2QjtRQUFDLE9BQU8sS0FBSyxFQUFFO1lBQ2QsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQ2Y7SUFDSCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRCxVQUFVO0FBQ1YsTUFBTSxVQUFVLHNCQUFzQixDQUFDLFNBQWU7SUFDcEQsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtRQUNyQyxNQUFNLE1BQU0sR0FBRyxJQUFJLFVBQVUsRUFBRSxDQUFDO1FBRWhDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsR0FBRyxFQUFFO1lBQ25CLE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxNQUFnQixDQUFDO1lBQzdDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLDZDQUE2QztRQUN0RSxDQUFDLENBQUM7UUFFRixNQUFNLENBQUMsT0FBTyxHQUFHLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDekIsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMseUNBQXlDO1FBQzFELENBQUMsQ0FBQztRQUVGLE1BQU0sQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDbEMsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQsVUFBVTtBQUNWLE1BQU0sVUFBZ0IsdUJBQXVCLENBQzNDLEtBQXVCLEVBQ3ZCLE9BQWdCOztRQUVoQixNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ2hELE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFeEMsTUFBTSxXQUFXLEdBQUcsS0FBSyxDQUFDLFVBQVUsQ0FBQztRQUNyQyxNQUFNLFlBQVksR0FBRyxLQUFLLENBQUMsV0FBVyxDQUFDO1FBQ3ZDLE1BQU0sWUFBWSxHQUFHLEtBQUssQ0FBQyxXQUFXLENBQUM7UUFDdkMsTUFBTSxhQUFhLEdBQUcsS0FBSyxDQUFDLFlBQVksQ0FBQztRQUV6QyxNQUFNLFdBQVcsR0FBRyxXQUFXLEdBQUcsWUFBWSxDQUFDO1FBQy9DLE1BQU0sWUFBWSxHQUFHLFlBQVksR0FBRyxhQUFhLENBQUM7UUFFbEQsSUFBSSxXQUFXLENBQUM7UUFDaEIsSUFBSSxZQUFZLENBQUM7UUFFakIsSUFBSSxXQUFXLElBQUksWUFBWSxFQUFFO1lBQy9CLDBCQUEwQjtZQUMxQixNQUFNLFdBQVcsR0FBRyxhQUFhLEdBQUcsWUFBWSxDQUFDO1lBRWpELFdBQVcsR0FBRyxXQUFXLEdBQUcsV0FBVyxDQUFDO1lBQ3hDLFlBQVksR0FBRyxZQUFZLEdBQUcsV0FBVyxDQUFDO1NBQzNDO2FBQU07WUFDTCx5QkFBeUI7WUFDekIsTUFBTSxVQUFVLEdBQUcsWUFBWSxHQUFHLFdBQVcsQ0FBQztZQUU5QyxXQUFXLEdBQUcsV0FBVyxHQUFHLFVBQVUsQ0FBQztZQUN2QyxZQUFZLEdBQUcsWUFBWSxHQUFHLFVBQVUsQ0FBQztTQUMxQztRQUVELE1BQU0sQ0FBQyxLQUFLLEdBQUcsV0FBVyxDQUFDO1FBQzNCLE1BQU0sQ0FBQyxNQUFNLEdBQUcsWUFBWSxDQUFDO1FBRTdCLElBQUksT0FBTyxFQUFFO1lBQ1gsT0FBTyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ25DLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7U0FDdEI7UUFFRCxPQUFPLENBQUMsU0FBUyxDQUNmLEtBQUssRUFDTCxDQUFDLEVBQ0QsQ0FBQyxFQUNELFdBQVcsRUFDWCxZQUFZLEVBQ1osQ0FBQyxFQUNELENBQUMsRUFDRCxXQUFXLEVBQ1gsWUFBWSxDQUNiLENBQUM7UUFFRixnRUFBZ0U7UUFDaEUsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUVsRCxNQUFNLEtBQUssR0FBRyxDQUFDLE1BQU0sa0JBQWtCLENBQUMsV0FBVyxDQUFDLENBQXFCLENBQUM7UUFFMUUsT0FBTyxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsQ0FBQztJQUNoQyxDQUFDO0NBQUE7QUFFRCxVQUFVO0FBQ1YsTUFBTSxVQUFnQixlQUFlLENBQ25DLEtBQXVCLEVBQ3ZCLGFBQXFCLEVBQ3JCLGNBQXNCOztRQUV0QixNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ2hELE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFeEMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUM3QyxNQUFNLEVBQUUsR0FBRyxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQy9DLE1BQU0sTUFBTSxHQUFHLGFBQWEsQ0FBQztRQUM3QixNQUFNLE9BQU8sR0FBRyxjQUFjLENBQUM7UUFDL0IsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ2IsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ2IsTUFBTSxNQUFNLEdBQUcsYUFBYSxDQUFDO1FBQzdCLE1BQU0sT0FBTyxHQUFHLGNBQWMsQ0FBQztRQUUvQixNQUFNLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQztRQUN0QixNQUFNLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FBQztRQUV4QixPQUFPLENBQUMsSUFBSSxFQUFFLENBQUM7UUFFZixPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN4QixPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUVwQixPQUFPLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFM0UsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBRWxCLE1BQU0sa0JBQWtCLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUV6RCxNQUFNLFlBQVksR0FBRyxDQUFDLE1BQU0sa0JBQWtCLENBQzVDLGtCQUFrQixDQUNuQixDQUFxQixDQUFDO1FBRXZCLE9BQU8sRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBRSxrQkFBa0IsRUFBRSxDQUFDO0lBQ2xFLENBQUM7Q0FBQTtBQUVELFVBQVU7QUFDVixNQUFNLFVBQWdCLHVCQUF1QixDQUMzQyxLQUF1QixFQUN2QixTQUFpQixFQUNqQixRQUFnQixFQUNoQixhQUFxQixFQUNyQixjQUFzQjs7UUFFdEIsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNoRCxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRXhDLE1BQU0sRUFBRSxHQUFHLFNBQVMsQ0FBQztRQUNyQixNQUFNLEVBQUUsR0FBRyxRQUFRLENBQUM7UUFDcEIsTUFBTSxNQUFNLEdBQUcsYUFBYSxDQUFDO1FBQzdCLE1BQU0sT0FBTyxHQUFHLGNBQWMsQ0FBQztRQUMvQixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDYixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDYixNQUFNLE1BQU0sR0FBRyxhQUFhLENBQUM7UUFDN0IsTUFBTSxPQUFPLEdBQUcsY0FBYyxDQUFDO1FBRS9CLE1BQU0sQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFDO1FBQ3RCLE1BQU0sQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDO1FBRXhCLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUVmLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3hCLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRXBCLE9BQU8sQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQztRQUUzRSxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7UUFFbEIsTUFBTSxrQkFBa0IsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRXpELE1BQU0sWUFBWSxHQUFHLENBQUMsTUFBTSxrQkFBa0IsQ0FDNUMsa0JBQWtCLENBQ25CLENBQXFCLENBQUM7UUFFdkIsT0FBTyxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLGtCQUFrQixFQUFFLENBQUM7SUFDbEUsQ0FBQztDQUFBO0FBRUQsTUFBTSxVQUFVLHFCQUFxQixDQUFDLEtBQVU7SUFDOUMsSUFBSSxZQUFZLENBQUMsS0FBSyxDQUFDLEVBQUU7UUFDdkIsT0FBTyxFQUFFLENBQUM7S0FDWDtJQUVELElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRTtRQUN4QixPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLE9BQU8sR0FBRyxLQUFLLFFBQVEsSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQyxDQUFDO0tBQ3pFO0lBRUQsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLEVBQUU7UUFDN0IsT0FBTyxLQUFLLENBQUM7S0FDZDtJQUVELE9BQU8sRUFBRSxDQUFDO0FBQ1osQ0FBQztBQUVELFVBQVU7QUFDVixNQUFNLFVBQWdCLG1CQUFtQixDQUN2QyxLQUF1QixFQUN2QixJQUFTOztRQU1ULElBQUksWUFBWSxDQUFDLEtBQUssQ0FBQyxFQUFFO1lBQ3ZCLE1BQU0sSUFBSSxLQUFLLENBQUMscUNBQXFDLENBQUMsQ0FBQztTQUN4RDtRQUNELElBQUksWUFBWSxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQ3RCLE9BQU87Z0JBQ0wsS0FBSztnQkFDTCxXQUFXLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQyxLQUFLLENBQUM7Z0JBQzVDLFlBQVksRUFBRSxvQ0FBb0M7YUFDbkQsQ0FBQztTQUNIO1FBRUQsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNoRCxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRXhDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQztRQUMzQixNQUFNLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUM7UUFFN0IsT0FBTyxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRS9CLE9BQU8sQ0FBQyxJQUFJLEdBQUcsWUFBWSxDQUFDO1FBQzVCLE9BQU8sQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDO1FBQzNCLE9BQU8sQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDO1FBQzdCLE9BQU8sQ0FBQyxTQUFTLEdBQUcsV0FBVyxDQUFDO1FBRWhDLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQ25ELElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQzlELENBQUM7UUFDRixNQUFNLGNBQWMsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztRQUVuRSxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsY0FBYyxHQUFHLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNsRCxPQUFPLENBQUMsU0FBUyxHQUFHLFFBQVEsQ0FBQztRQUU3QixJQUFJLE1BQU0sR0FBRyxFQUFFLENBQUM7UUFDaEIsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLEVBQUU7WUFDdEIsSUFBSSxlQUFlLENBQUMsR0FBRyxDQUFDLEVBQUU7Z0JBQ3hCLE9BQU8sQ0FBQyxRQUFRLENBQ2QsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxpQkFBaUIsRUFBRSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUMvRCxFQUFFLEVBQ0YsTUFBTSxDQUNQLENBQUM7Z0JBQ0YsTUFBTSxJQUFJLEVBQUUsQ0FBQzthQUNkO1NBQ0Y7UUFFRCxNQUFNLHNCQUFzQixHQUFXLE1BQU0sQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFckUsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLE1BQU0sa0JBQWtCLENBQ2hELHNCQUFzQixDQUN2QixDQUFxQixDQUFDO1FBRXZCLE9BQU8sRUFBRSxLQUFLLEVBQUUsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLHNCQUFzQixFQUFFLENBQUM7SUFDMUUsQ0FBQztDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaXNFbXB0eVZhbHVlLCBpc05vdEVtcHR5VmFsdWUgfSBmcm9tIFwia3dpa2lkLXRvb2xraXRcIjtcblxuLy8gVE9PTEtJVFxuZXhwb3J0IGZ1bmN0aW9uIGZsaXBJbWFnZUhvcml6b250YWxseShiYXNlNjRJbWFnZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgLy8gQ3JlYXRlIGFuIEhUTUwgaW1hZ2UgZWxlbWVudFxuICBjb25zdCBpbWcgPSBuZXcgSW1hZ2UoKTtcbiAgaW1nLnNyYyA9IGJhc2U2NEltYWdlO1xuXG4gIC8vIENyZWF0ZSBhIGNhbnZhcyBlbGVtZW50XG4gIGNvbnN0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIik7XG4gIGNvbnN0IGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIik7XG5cbiAgLy8gU2V0IHRoZSBjYW52YXMgZGltZW5zaW9ucyB0byBtYXRjaCB0aGUgaW1hZ2VcbiAgY2FudmFzLndpZHRoID0gaW1nLndpZHRoO1xuICBjYW52YXMuaGVpZ2h0ID0gaW1nLmhlaWdodDtcblxuICAvLyBEcmF3IHRoZSBpbWFnZSBvbiB0aGUgY2FudmFzLCBmbGlwcGVkIGhvcml6b250YWxseVxuICBjdHguc2NhbGUoLTEsIDEpOyAvLyBGbGlwIGhvcml6b250YWxseVxuICBjdHguZHJhd0ltYWdlKGltZywgLWNhbnZhcy53aWR0aCwgMCwgY2FudmFzLndpZHRoLCBjYW52YXMuaGVpZ2h0KTtcblxuICAvLyBDb252ZXJ0IHRoZSBjYW52YXMgY29udGVudCB0byBhIGJhc2U2NCBzdHJpbmdcbiAgY29uc3QgZmxpcHBlZEJhc2U2NCA9IGNhbnZhcy50b0RhdGFVUkwoKTtcblxuICByZXR1cm4gZmxpcHBlZEJhc2U2NDtcbn1cblxuLy8gVE9PTEtJVFxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldERldmljZXNMaXN0KCk6IFByb21pc2U8YW55PiB7XG4gIGNvbnN0IHZpZGVvRGV2aWNlczogYW55W10gPSBbXTtcblxuICBhd2FpdCBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmVudW1lcmF0ZURldmljZXMoKS50aGVuKChkZXZpY2VzKSA9PiB7XG4gICAgZm9yIChjb25zdCBkZXZpY2Ugb2YgZGV2aWNlcykge1xuICAgICAgaWYgKGRldmljZS5raW5kID09PSBcInZpZGVvaW5wdXRcIikge1xuICAgICAgICB2aWRlb0RldmljZXMucHVzaChkZXZpY2UpO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHZpZGVvRGV2aWNlcztcbn1cblxuLy8gVE9PTEtJVFxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldERldmljZUlkKGFjdGl2ZURldmljZUlkOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICBsZXQgZGV2aWNlSWQ6IHN0cmluZyA9IGFjdGl2ZURldmljZUlkO1xuICBjb25zdCB2aWRlb0RldmljZXM6IGFueVtdID0gW107XG5cbiAgYXdhaXQgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5lbnVtZXJhdGVEZXZpY2VzKCkudGhlbigoZGV2aWNlcykgPT4ge1xuICAgIGZvciAoY29uc3QgZGV2aWNlIG9mIGRldmljZXMpIHtcbiAgICAgIGlmIChkZXZpY2Uua2luZCA9PT0gXCJ2aWRlb2lucHV0XCIpIHtcbiAgICAgICAgdmlkZW9EZXZpY2VzLnB1c2goZGV2aWNlKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIGlmICh2aWRlb0RldmljZXMubGVuZ3RoID09PSAxIHx8IGlzRW1wdHlWYWx1ZShhY3RpdmVEZXZpY2VJZCkpIHtcbiAgICBkZXZpY2VJZCA9IHZpZGVvRGV2aWNlc1swXS5kZXZpY2VJZDtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBmaWx0ZXJlZFZpZGVvRGV2aWNlID0gdmlkZW9EZXZpY2VzLmZpbHRlcigodmlkZW9EZXZpY2UpID0+IHtcbiAgICAgIHJldHVybiB2aWRlb0RldmljZS5kZXZpY2VJZCAhPT0gYWN0aXZlRGV2aWNlSWQ7XG4gICAgfSlbMF07XG5cbiAgICBkZXZpY2VJZCA9IGZpbHRlcmVkVmlkZW9EZXZpY2UuZGV2aWNlSWQ7XG4gIH1cblxuICByZXR1cm4gZGV2aWNlSWQ7XG59XG5cbi8vIFRPT0xLSVRcbmV4cG9ydCBmdW5jdGlvbiBnZXRJbWFnZUZyb21CYXNlNjQoXG4gIGJhc2U2NFN0cmluZzogc3RyaW5nXG4pOiBQcm9taXNlPEhUTUxJbWFnZUVsZW1lbnQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCBpbWFnZSA9IG5ldyBJbWFnZSgpO1xuXG4gICAgaW1hZ2Uub25sb2FkID0gKCkgPT4ge1xuICAgICAgcmVzb2x2ZShpbWFnZSk7XG4gICAgfTtcblxuICAgIGltYWdlLm9uZXJyb3IgPSAoZXJyb3IpID0+IHtcbiAgICAgIHJlamVjdChlcnJvcik7XG4gICAgfTtcblxuICAgIGltYWdlLnNyYyA9IGJhc2U2NFN0cmluZztcbiAgfSk7XG59XG5cbi8vIFRPT0xLSVRcbmV4cG9ydCBmdW5jdGlvbiBnZXRCYXNlNjRGcm9tSW1hZ2UoaW1hZ2U6IEhUTUxJbWFnZUVsZW1lbnQpOiBQcm9taXNlPHN0cmluZz4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIik7XG4gICAgY29uc3QgY29udGV4dCA9IGNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIik7XG5cbiAgICBjYW52YXMud2lkdGggPSBpbWFnZS53aWR0aDtcbiAgICBjYW52YXMuaGVpZ2h0ID0gaW1hZ2UuaGVpZ2h0O1xuXG4gICAgY29udGV4dC5kcmF3SW1hZ2UoaW1hZ2UsIDAsIDAsIGltYWdlLndpZHRoLCBpbWFnZS5oZWlnaHQpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGJhc2U2NFN0cmluZyA9IGNhbnZhcy50b0RhdGFVUkwoXCJpbWFnZS9wbmdcIik7XG4gICAgICByZXNvbHZlKGJhc2U2NFN0cmluZyk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJlamVjdChlcnJvcik7XG4gICAgfVxuICB9KTtcbn1cblxuLy8gVE9PTEtJVFxuZXhwb3J0IGZ1bmN0aW9uIGdldEJhc2U2NEZyb21JbWFnZUZpbGUoaW1hZ2VGaWxlOiBGaWxlKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpO1xuXG4gICAgcmVhZGVyLm9ubG9hZCA9ICgpID0+IHtcbiAgICAgIGNvbnN0IGJhc2U2NFN0cmluZyA9IHJlYWRlci5yZXN1bHQgYXMgc3RyaW5nO1xuICAgICAgcmVzb2x2ZShiYXNlNjRTdHJpbmcpOyAvLyBSZXNvbHZlIHRoZSBQcm9taXNlIHdpdGggdGhlIGJhc2U2NCBzdHJpbmdcbiAgICB9O1xuXG4gICAgcmVhZGVyLm9uZXJyb3IgPSAoZXJyb3IpID0+IHtcbiAgICAgIHJlamVjdChlcnJvcik7IC8vIFJlamVjdCB0aGUgUHJvbWlzZSBpbiBjYXNlIG9mIGFuIGVycm9yXG4gICAgfTtcblxuICAgIHJlYWRlci5yZWFkQXNEYXRhVVJMKGltYWdlRmlsZSk7XG4gIH0pO1xufVxuXG4vLyBUT09MS0lUXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0U2NhbGVkSW1hZ2VGcm9tVmlkZW8oXG4gIHZpZGVvOiBIVE1MVmlkZW9FbGVtZW50LFxuICBmbGlwcGVkOiBib29sZWFuXG4pOiBQcm9taXNlPHsgaW1hZ2U6IEhUTUxJbWFnZUVsZW1lbnQ7IGltYWdlQmFzZTY0OiBzdHJpbmcgfT4ge1xuICBjb25zdCBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiY2FudmFzXCIpO1xuICBjb25zdCBjb250ZXh0ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcblxuICBjb25zdCBjYW1lcmFXaWR0aCA9IHZpZGVvLnZpZGVvV2lkdGg7XG4gIGNvbnN0IGNhbWVyYUhlaWdodCA9IHZpZGVvLnZpZGVvSGVpZ2h0O1xuICBjb25zdCB2aXNpYmxlV2lkdGggPSB2aWRlby5jbGllbnRXaWR0aDtcbiAgY29uc3QgdmlzaWJsZUhlaWdodCA9IHZpZGVvLmNsaWVudEhlaWdodDtcblxuICBjb25zdCBjYW1lcmFSYXRpbyA9IGNhbWVyYVdpZHRoIC8gY2FtZXJhSGVpZ2h0O1xuICBjb25zdCB2aXNpYmxlUmF0aW8gPSB2aXNpYmxlV2lkdGggLyB2aXNpYmxlSGVpZ2h0O1xuXG4gIGxldCBzY2FsZWRXaWR0aDtcbiAgbGV0IHNjYWxlZEhlaWdodDtcblxuICBpZiAoY2FtZXJhUmF0aW8gPj0gdmlzaWJsZVJhdGlvKSB7XG4gICAgLy8gU2NhbGUgdG8gVmlzaWJsZSBIZWlnaHRcbiAgICBjb25zdCBoZWlnaHRSYXRpbyA9IHZpc2libGVIZWlnaHQgLyBjYW1lcmFIZWlnaHQ7XG5cbiAgICBzY2FsZWRXaWR0aCA9IGNhbWVyYVdpZHRoICogaGVpZ2h0UmF0aW87XG4gICAgc2NhbGVkSGVpZ2h0ID0gY2FtZXJhSGVpZ2h0ICogaGVpZ2h0UmF0aW87XG4gIH0gZWxzZSB7XG4gICAgLy8gU2NhbGUgdG8gVmlzaWJsZSBXaWR0aFxuICAgIGNvbnN0IHdpZHRoUmF0aW8gPSB2aXNpYmxlV2lkdGggLyBjYW1lcmFXaWR0aDtcblxuICAgIHNjYWxlZFdpZHRoID0gY2FtZXJhV2lkdGggKiB3aWR0aFJhdGlvO1xuICAgIHNjYWxlZEhlaWdodCA9IGNhbWVyYUhlaWdodCAqIHdpZHRoUmF0aW87XG4gIH1cblxuICBjYW52YXMud2lkdGggPSBzY2FsZWRXaWR0aDtcbiAgY2FudmFzLmhlaWdodCA9IHNjYWxlZEhlaWdodDtcblxuICBpZiAoZmxpcHBlZCkge1xuICAgIGNvbnRleHQudHJhbnNsYXRlKGNhbnZhcy53aWR0aCwgMCk7XG4gICAgY29udGV4dC5zY2FsZSgtMSwgMSk7XG4gIH1cblxuICBjb250ZXh0LmRyYXdJbWFnZShcbiAgICB2aWRlbyxcbiAgICAwLFxuICAgIDAsXG4gICAgY2FtZXJhV2lkdGgsXG4gICAgY2FtZXJhSGVpZ2h0LFxuICAgIDAsXG4gICAgMCxcbiAgICBzY2FsZWRXaWR0aCxcbiAgICBzY2FsZWRIZWlnaHRcbiAgKTtcblxuICAvLyBHZXQgdGhlIGltYWdlIGRhdGEgZnJvbSB0aGUgY2FudmFzIGFzIGEgYmFzZTY0LWVuY29kZWQgc3RyaW5nXG4gIGNvbnN0IGltYWdlQmFzZTY0ID0gY2FudmFzLnRvRGF0YVVSTChcImltYWdlL3BuZ1wiKTtcblxuICBjb25zdCBpbWFnZSA9IChhd2FpdCBnZXRJbWFnZUZyb21CYXNlNjQoaW1hZ2VCYXNlNjQpKSBhcyBIVE1MSW1hZ2VFbGVtZW50O1xuXG4gIHJldHVybiB7IGltYWdlLCBpbWFnZUJhc2U2NCB9O1xufVxuXG4vLyBUT09MS0lUXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0Q3JvcHBlZEltYWdlKFxuICBpbWFnZTogSFRNTEltYWdlRWxlbWVudCxcbiAgcmVxdWlyZWRXaWR0aDogbnVtYmVyLFxuICByZXF1aXJlZEhlaWdodDogbnVtYmVyXG4pOiBQcm9taXNlPHsgaW1hZ2U6IEhUTUxJbWFnZUVsZW1lbnQ7IGltYWdlQmFzZTY0OiBzdHJpbmcgfT4ge1xuICBjb25zdCBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiY2FudmFzXCIpO1xuICBjb25zdCBjb250ZXh0ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcblxuICBjb25zdCBzeCA9IChpbWFnZS53aWR0aCAtIHJlcXVpcmVkV2lkdGgpIC8gMjtcbiAgY29uc3Qgc3kgPSAoaW1hZ2UuaGVpZ2h0IC0gcmVxdWlyZWRIZWlnaHQpIC8gMjtcbiAgY29uc3Qgc1dpZHRoID0gcmVxdWlyZWRXaWR0aDtcbiAgY29uc3Qgc0hlaWdodCA9IHJlcXVpcmVkSGVpZ2h0O1xuICBjb25zdCBkeCA9IDA7XG4gIGNvbnN0IGR5ID0gMDtcbiAgY29uc3QgZFdpZHRoID0gcmVxdWlyZWRXaWR0aDtcbiAgY29uc3QgZEhlaWdodCA9IHJlcXVpcmVkSGVpZ2h0O1xuXG4gIGNhbnZhcy53aWR0aCA9IGRXaWR0aDtcbiAgY2FudmFzLmhlaWdodCA9IGRIZWlnaHQ7XG5cbiAgY29udGV4dC5zYXZlKCk7XG5cbiAgY29udGV4dC50cmFuc2xhdGUoMCwgMCk7XG4gIGNvbnRleHQuc2NhbGUoMSwgMSk7XG5cbiAgY29udGV4dC5kcmF3SW1hZ2UoaW1hZ2UsIHN4LCBzeSwgc1dpZHRoLCBzSGVpZ2h0LCBkeCwgZHksIGRXaWR0aCwgZEhlaWdodCk7XG5cbiAgY29udGV4dC5yZXN0b3JlKCk7XG5cbiAgY29uc3QgY3JvcHBlZEltYWdlQmFzZTY0ID0gY2FudmFzLnRvRGF0YVVSTChcImltYWdlL3BuZ1wiKTtcblxuICBjb25zdCBjcm9wcGVkSW1hZ2UgPSAoYXdhaXQgZ2V0SW1hZ2VGcm9tQmFzZTY0KFxuICAgIGNyb3BwZWRJbWFnZUJhc2U2NFxuICApKSBhcyBIVE1MSW1hZ2VFbGVtZW50O1xuXG4gIHJldHVybiB7IGltYWdlOiBjcm9wcGVkSW1hZ2UsIGltYWdlQmFzZTY0OiBjcm9wcGVkSW1hZ2VCYXNlNjQgfTtcbn1cblxuLy8gVE9PTEtJVFxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldENyb3BwZWRJbWFnZUZyb21NYXNrKFxuICBpbWFnZTogSFRNTEltYWdlRWxlbWVudCxcbiAgbGVmdFNoaWZ0OiBudW1iZXIsXG4gIHRvcFNoaWZ0OiBudW1iZXIsXG4gIHJlcXVpcmVkV2lkdGg6IG51bWJlcixcbiAgcmVxdWlyZWRIZWlnaHQ6IG51bWJlclxuKTogUHJvbWlzZTx7IGltYWdlOiBIVE1MSW1hZ2VFbGVtZW50OyBpbWFnZUJhc2U2NDogc3RyaW5nIH0+IHtcbiAgY29uc3QgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgY29uc3QgY29udGV4dCA9IGNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIik7XG5cbiAgY29uc3Qgc3ggPSBsZWZ0U2hpZnQ7XG4gIGNvbnN0IHN5ID0gdG9wU2hpZnQ7XG4gIGNvbnN0IHNXaWR0aCA9IHJlcXVpcmVkV2lkdGg7XG4gIGNvbnN0IHNIZWlnaHQgPSByZXF1aXJlZEhlaWdodDtcbiAgY29uc3QgZHggPSAwO1xuICBjb25zdCBkeSA9IDA7XG4gIGNvbnN0IGRXaWR0aCA9IHJlcXVpcmVkV2lkdGg7XG4gIGNvbnN0IGRIZWlnaHQgPSByZXF1aXJlZEhlaWdodDtcblxuICBjYW52YXMud2lkdGggPSBkV2lkdGg7XG4gIGNhbnZhcy5oZWlnaHQgPSBkSGVpZ2h0O1xuXG4gIGNvbnRleHQuc2F2ZSgpO1xuXG4gIGNvbnRleHQudHJhbnNsYXRlKDAsIDApO1xuICBjb250ZXh0LnNjYWxlKDEsIDEpO1xuXG4gIGNvbnRleHQuZHJhd0ltYWdlKGltYWdlLCBzeCwgc3ksIHNXaWR0aCwgc0hlaWdodCwgZHgsIGR5LCBkV2lkdGgsIGRIZWlnaHQpO1xuXG4gIGNvbnRleHQucmVzdG9yZSgpO1xuXG4gIGNvbnN0IGNyb3BwZWRJbWFnZUJhc2U2NCA9IGNhbnZhcy50b0RhdGFVUkwoXCJpbWFnZS9wbmdcIik7XG5cbiAgY29uc3QgY3JvcHBlZEltYWdlID0gKGF3YWl0IGdldEltYWdlRnJvbUJhc2U2NChcbiAgICBjcm9wcGVkSW1hZ2VCYXNlNjRcbiAgKSkgYXMgSFRNTEltYWdlRWxlbWVudDtcblxuICByZXR1cm4geyBpbWFnZTogY3JvcHBlZEltYWdlLCBpbWFnZUJhc2U2NDogY3JvcHBlZEltYWdlQmFzZTY0IH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb3JyZWN0SW1hZ2VGb3JtYXQoaW1hZ2U6IGFueSk6IHN0cmluZyB7XG4gIGlmIChpc0VtcHR5VmFsdWUoaW1hZ2UpKSB7XG4gICAgcmV0dXJuIFwiXCI7XG4gIH1cblxuICBpZiAoQXJyYXkuaXNBcnJheShpbWFnZSkpIHtcbiAgICByZXR1cm4gaW1hZ2UuZmluZCgoaW1nKSA9PiB0eXBlb2YgaW1nID09PSBcInN0cmluZ1wiICYmIGltZy5sZW5ndGggIT09IDApO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBpbWFnZSA9PT0gXCJzdHJpbmdcIikge1xuICAgIHJldHVybiBpbWFnZTtcbiAgfVxuXG4gIHJldHVybiBcIlwiO1xufVxuXG4vLyBUT09MS0lUXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0V2F0ZXJtYXJrZWRJbWFnZShcbiAgaW1hZ2U6IEhUTUxJbWFnZUVsZW1lbnQsXG4gIGRhdGE6IGFueVxuKTogUHJvbWlzZTx7XG4gIGltYWdlOiBIVE1MSW1hZ2VFbGVtZW50O1xuICBpbWFnZUJhc2U2NDogc3RyaW5nO1xuICBlcnJvck1lc3NhZ2U/OiBzdHJpbmc7XG59PiB7XG4gIGlmIChpc0VtcHR5VmFsdWUoaW1hZ2UpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gaW1hZ2UgcHJvdmlkZWQgZm9yIHdhdGVybWFya2luZyFcIik7XG4gIH1cbiAgaWYgKGlzRW1wdHlWYWx1ZShkYXRhKSkge1xuICAgIHJldHVybiB7XG4gICAgICBpbWFnZSxcbiAgICAgIGltYWdlQmFzZTY0OiBhd2FpdCBnZXRCYXNlNjRGcm9tSW1hZ2UoaW1hZ2UpLFxuICAgICAgZXJyb3JNZXNzYWdlOiBcIk5vIGRhdGEgcHJvdmlkZWQgZm9yIHdhdGVybWFya2luZyFcIlxuICAgIH07XG4gIH1cblxuICBjb25zdCBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiY2FudmFzXCIpO1xuICBjb25zdCBjb250ZXh0ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcblxuICBjYW52YXMud2lkdGggPSBpbWFnZS53aWR0aDtcbiAgY2FudmFzLmhlaWdodCA9IGltYWdlLmhlaWdodDtcblxuICBjb250ZXh0LmRyYXdJbWFnZShpbWFnZSwgMCwgMCk7XG5cbiAgY29udGV4dC5mb250ID0gXCIxMnB4IEFyaWFsXCI7XG4gIGNvbnRleHQudGV4dEFsaWduID0gXCJsZWZ0XCI7XG4gIGNvbnRleHQudGV4dEJhc2VsaW5lID0gXCJ0b3BcIjtcbiAgY29udGV4dC5maWxsU3R5bGUgPSBcIiNhMmEyYTJjN1wiO1xuXG4gIGNvbnN0IGxvbmdlc3RLZXkgPSBPYmplY3Qua2V5cyhkYXRhKS5yZWR1Y2UoKGEsIGIpID0+XG4gICAgZGF0YVthXS50b1N0cmluZygpLmxlbmd0aCA+IGRhdGFbYl0udG9TdHJpbmcoKS5sZW5ndGggPyBhIDogYlxuICApO1xuICBjb25zdCByZWN0YW5nbGVXaWR0aCA9IGNvbnRleHQubWVhc3VyZVRleHQoZGF0YVtsb25nZXN0S2V5XSkud2lkdGg7XG5cbiAgY29udGV4dC5maWxsUmVjdCgxMCwgMTAsIHJlY3RhbmdsZVdpZHRoICsgOTUsIDcwKTtcbiAgY29udGV4dC5maWxsU3R5bGUgPSBcInllbGxvd1wiO1xuXG4gIGxldCB5SW5kZXggPSAyMDtcbiAgZm9yIChjb25zdCBrZXkgaW4gZGF0YSkge1xuICAgIGlmIChpc05vdEVtcHR5VmFsdWUoa2V5KSkge1xuICAgICAgY29udGV4dC5maWxsVGV4dChcbiAgICAgICAgYCR7a2V5LnNwbGl0KFwiX1wiKS5qb2luKFwiIFwiKS50b0xvY2FsZVVwcGVyQ2FzZSgpfTogJHtkYXRhW2tleV19YCxcbiAgICAgICAgMjAsXG4gICAgICAgIHlJbmRleFxuICAgICAgKTtcbiAgICAgIHlJbmRleCArPSAyMDtcbiAgICB9XG4gIH1cblxuICBjb25zdCB3YXRlcm1hcmtlZEltYWdlQmFzZTY0OiBzdHJpbmcgPSBjYW52YXMudG9EYXRhVVJMKFwiaW1hZ2UvcG5nXCIpO1xuXG4gIGNvbnN0IHdhdGVybWFya2VkSW1hZ2UgPSAoYXdhaXQgZ2V0SW1hZ2VGcm9tQmFzZTY0KFxuICAgIHdhdGVybWFya2VkSW1hZ2VCYXNlNjRcbiAgKSkgYXMgSFRNTEltYWdlRWxlbWVudDtcblxuICByZXR1cm4geyBpbWFnZTogd2F0ZXJtYXJrZWRJbWFnZSwgaW1hZ2VCYXNlNjQ6IHdhdGVybWFya2VkSW1hZ2VCYXNlNjQgfTtcbn1cbiJdfQ==