payload
Version:
Node, React and MongoDB Headless CMS and Application Framework
392 lines (391 loc) • 48.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "EditUpload", {
enumerable: true,
get: function() {
return EditUpload;
}
});
const _modal = require("@faceless-ui/modal");
const _react = /*#__PURE__*/ _interop_require_wildcard(require("react"));
const _reacti18next = require("react-i18next");
const _reactimagecrop = /*#__PURE__*/ _interop_require_default(require("react-image-crop"));
require("react-image-crop/dist/ReactCrop.css");
const _Plus = /*#__PURE__*/ _interop_require_default(require("../../icons/Plus"));
const _FormQueryParams = require("../../utilities/FormQueryParams");
const _Upload = require("../../views/collections/Edit/Upload");
const _Button = /*#__PURE__*/ _interop_require_default(require("../Button"));
require("./index.scss");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function _getRequireWildcardCache(nodeInterop) {
if (typeof WeakMap !== "function") return null;
var cacheBabelInterop = new WeakMap();
var cacheNodeInterop = new WeakMap();
return (_getRequireWildcardCache = function(nodeInterop) {
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
})(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
if (!nodeInterop && obj && obj.__esModule) {
return obj;
}
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
return {
default: obj
};
}
var cache = _getRequireWildcardCache(nodeInterop);
if (cache && cache.has(obj)) {
return cache.get(obj);
}
var newObj = {
__proto__: null
};
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
for(var key in obj){
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
if (desc && (desc.get || desc.set)) {
Object.defineProperty(newObj, key, desc);
} else {
newObj[key] = obj[key];
}
}
}
newObj.default = obj;
if (cache) {
cache.set(obj, newObj);
}
return newObj;
}
const baseClass = 'edit-upload';
const Input = ({ name, onChange, value })=>/*#__PURE__*/ _react.default.createElement("div", {
className: `${baseClass}__input`
}, name, /*#__PURE__*/ _react.default.createElement("input", {
name: name,
onChange: (e)=>onChange(e.target.value),
type: "number",
value: value
}));
const EditUpload = ({ fileName, fileSrc, imageCacheTag, showCrop, showFocalPoint })=>{
const { closeModal } = (0, _modal.useModal)();
const { t } = (0, _reacti18next.useTranslation)([
'general',
'upload'
]);
const { formQueryParams, setFormQueryParams } = (0, _FormQueryParams.useFormQueryParams)();
const { uploadEdits } = formQueryParams || {};
const [crop, setCrop] = (0, _react.useState)({
height: uploadEdits?.crop?.height || 100,
unit: '%',
width: uploadEdits?.crop?.width || 100,
x: uploadEdits?.crop?.x || 0,
y: uploadEdits?.crop?.y || 0
});
const [pointPosition, setPointPosition] = (0, _react.useState)({
x: uploadEdits?.focalPoint?.x || 50,
y: uploadEdits?.focalPoint?.y || 50
});
const [checkBounds, setCheckBounds] = (0, _react.useState)(false);
const [originalHeight, setOriginalHeight] = (0, _react.useState)(0);
const [originalWidth, setOriginalWidth] = (0, _react.useState)(0);
const focalWrapRef = (0, _react.useRef)();
const imageRef = (0, _react.useRef)();
const cropRef = (0, _react.useRef)();
const fineTuneCrop = ({ dimension, value })=>{
const intValue = parseInt(value);
if (dimension === 'width' && intValue >= originalWidth) return null;
if (dimension === 'height' && intValue >= originalHeight) return null;
const percentage = 100 * (intValue / (dimension === 'width' ? originalWidth : originalHeight));
if (percentage === 100 || percentage === 0) return null;
setCrop({
...crop,
[dimension]: percentage
});
};
const fineTuneFocalPoint = ({ coordinate, value })=>{
const intValue = parseInt(value);
if (intValue >= 0 && intValue <= 100) {
setPointPosition((prevPosition)=>({
...prevPosition,
[coordinate]: intValue
}));
}
};
const saveEdits = ()=>{
setFormQueryParams({
...formQueryParams,
uploadEdits: {
crop: crop || undefined,
focalPoint: pointPosition ? pointPosition : undefined
}
});
closeModal(_Upload.editDrawerSlug);
};
const onDragEnd = _react.default.useCallback(({ x, y })=>{
setPointPosition({
x,
y
});
setCheckBounds(false);
}, []);
const centerFocalPoint = ()=>{
const containerRect = focalWrapRef.current.getBoundingClientRect();
const boundsRect = showCrop ? cropRef.current.getBoundingClientRect() : imageRef.current.getBoundingClientRect();
const xCenter = (boundsRect.left - containerRect.left + boundsRect.width / 2) / containerRect.width * 100;
const yCenter = (boundsRect.top - containerRect.top + boundsRect.height / 2) / containerRect.height * 100;
setPointPosition({
x: xCenter,
y: yCenter
});
};
const fileSrcToUse = imageCacheTag ? `${fileSrc}?${imageCacheTag}` : fileSrc;
return /*#__PURE__*/ _react.default.createElement("div", {
className: baseClass
}, /*#__PURE__*/ _react.default.createElement("div", {
className: `${baseClass}__header`
}, /*#__PURE__*/ _react.default.createElement("h2", {
title: `${t('general:editing')} ${fileName}`
}, t('general:editing'), " ", fileName), /*#__PURE__*/ _react.default.createElement("div", {
className: `${baseClass}__actions`
}, /*#__PURE__*/ _react.default.createElement(_Button.default, {
"aria-label": t('cancel'),
buttonStyle: "secondary",
className: `${baseClass}__cancel`,
onClick: ()=>closeModal(_Upload.editDrawerSlug)
}, t('general:cancel')), /*#__PURE__*/ _react.default.createElement(_Button.default, {
"aria-label": t('general:applyChanges'),
buttonStyle: "primary",
className: `${baseClass}__save`,
onClick: ()=>saveEdits()
}, t('general:applyChanges')))), /*#__PURE__*/ _react.default.createElement("div", {
className: `${baseClass}__toolWrap`
}, /*#__PURE__*/ _react.default.createElement("div", {
className: `${baseClass}__crop`
}, /*#__PURE__*/ _react.default.createElement("div", {
className: `${baseClass}__focal-wrapper`,
ref: focalWrapRef,
style: {
aspectRatio: `${originalWidth / originalHeight}`
}
}, showCrop ? /*#__PURE__*/ _react.default.createElement(_reactimagecrop.default, {
className: `${baseClass}__reactCrop`,
crop: crop,
onChange: (_, c)=>setCrop(c),
onComplete: ()=>setCheckBounds(true),
renderSelectionAddon: ()=>{
return /*#__PURE__*/ _react.default.createElement("div", {
className: `${baseClass}__crop-window`,
ref: cropRef
});
}
}, /*#__PURE__*/ _react.default.createElement("img", {
alt: t('upload:setCropArea'),
onLoad: (e)=>{
setOriginalHeight(e.currentTarget.naturalHeight);
setOriginalWidth(e.currentTarget.naturalWidth);
},
ref: imageRef,
src: fileSrcToUse
})) : /*#__PURE__*/ _react.default.createElement("img", {
alt: t('upload:setFocalPoint'),
onLoad: (e)=>{
setOriginalHeight(e.currentTarget.naturalHeight);
setOriginalWidth(e.currentTarget.naturalWidth);
},
ref: imageRef,
src: fileSrcToUse
}), showFocalPoint && /*#__PURE__*/ _react.default.createElement(DraggableElement, {
boundsRef: showCrop ? cropRef : imageRef,
checkBounds: showCrop ? checkBounds : false,
className: `${baseClass}__focalPoint`,
containerRef: focalWrapRef,
initialPosition: pointPosition,
onDragEnd: onDragEnd,
setCheckBounds: showCrop ? setCheckBounds : false
}, /*#__PURE__*/ _react.default.createElement(_Plus.default, null)))), (showCrop || showFocalPoint) && /*#__PURE__*/ _react.default.createElement("div", {
className: `${baseClass}__sidebar`
}, showCrop && /*#__PURE__*/ _react.default.createElement("div", {
className: `${baseClass}__groupWrap`
}, /*#__PURE__*/ _react.default.createElement("div", null, /*#__PURE__*/ _react.default.createElement("div", {
className: `${baseClass}__titleWrap`
}, /*#__PURE__*/ _react.default.createElement("h3", null, t('upload:crop')), /*#__PURE__*/ _react.default.createElement(_Button.default, {
buttonStyle: "none",
className: `${baseClass}__reset`,
onClick: ()=>setCrop({
height: 100,
unit: '%',
width: 100,
x: 0,
y: 0
})
}, t('general:reset')))), /*#__PURE__*/ _react.default.createElement("span", {
className: `${baseClass}__description`
}, t('upload:cropToolDescription')), /*#__PURE__*/ _react.default.createElement("div", {
className: `${baseClass}__inputsWrap`
}, /*#__PURE__*/ _react.default.createElement(Input, {
name: `${t('upload:width')} (px)`,
onChange: (value)=>fineTuneCrop({
dimension: 'width',
value
}),
value: (crop.width / 100 * originalWidth).toFixed(0)
}), /*#__PURE__*/ _react.default.createElement(Input, {
name: `${t('upload:height')} (px)`,
onChange: (value)=>fineTuneCrop({
dimension: 'height',
value
}),
value: (crop.height / 100 * originalHeight).toFixed(0)
}))), showFocalPoint && /*#__PURE__*/ _react.default.createElement("div", {
className: `${baseClass}__groupWrap`
}, /*#__PURE__*/ _react.default.createElement("div", null, /*#__PURE__*/ _react.default.createElement("div", {
className: `${baseClass}__titleWrap`
}, /*#__PURE__*/ _react.default.createElement("h3", null, t('upload:focalPoint')), /*#__PURE__*/ _react.default.createElement(_Button.default, {
buttonStyle: "none",
className: `${baseClass}__reset`,
onClick: centerFocalPoint
}, t('general:reset')))), /*#__PURE__*/ _react.default.createElement("span", {
className: `${baseClass}__description`
}, t('upload:focalPointDescription')), /*#__PURE__*/ _react.default.createElement("div", {
className: `${baseClass}__inputsWrap`
}, /*#__PURE__*/ _react.default.createElement(Input, {
name: "X %",
onChange: (value)=>fineTuneFocalPoint({
coordinate: 'x',
value
}),
value: pointPosition.x.toFixed(0)
}), /*#__PURE__*/ _react.default.createElement(Input, {
name: "Y %",
onChange: (value)=>fineTuneFocalPoint({
coordinate: 'y',
value
}),
value: pointPosition.y.toFixed(0)
}))))));
};
const DraggableElement = ({ boundsRef, checkBounds, children, className, containerRef, initialPosition = {
x: 50,
y: 50
}, onDragEnd, setCheckBounds })=>{
const [position, setPosition] = (0, _react.useState)({
x: initialPosition.x,
y: initialPosition.y
});
const [isDragging, setIsDragging] = (0, _react.useState)(false);
const dragRef = (0, _react.useRef)();
const getCoordinates = _react.default.useCallback((mouseXArg, mouseYArg, recenter)=>{
const containerRect = containerRef.current.getBoundingClientRect();
const boundsRect = boundsRef.current.getBoundingClientRect();
const mouseX = mouseXArg ?? boundsRect.left;
const mouseY = mouseYArg ?? boundsRect.top;
const xOutOfBounds = mouseX < boundsRect.left || mouseX > boundsRect.right;
const yOutOfBounds = mouseY < boundsRect.top || mouseY > boundsRect.bottom;
let x = (mouseX - containerRect.left) / containerRect.width * 100;
let y = (mouseY - containerRect.top) / containerRect.height * 100;
const xCenter = (boundsRect.left - containerRect.left + boundsRect.width / 2) / containerRect.width * 100;
const yCenter = (boundsRect.top - containerRect.top + boundsRect.height / 2) / containerRect.height * 100;
if (xOutOfBounds || yOutOfBounds) {
setIsDragging(false);
if (mouseX < boundsRect.left) {
x = (boundsRect.left - containerRect.left) / containerRect.width * 100;
} else if (mouseX > boundsRect.right) {
x = (containerRect.width - (containerRect.right - boundsRect.right)) / containerRect.width * 100;
}
if (mouseY < boundsRect.top) {
y = (boundsRect.top - containerRect.top) / containerRect.height * 100;
} else if (mouseY > boundsRect.bottom) {
y = (containerRect.height - (containerRect.bottom - boundsRect.bottom)) / containerRect.height * 100;
}
if (recenter) {
x = xOutOfBounds ? xCenter : x;
y = yOutOfBounds ? yCenter : y;
}
}
return {
x,
y
};
}, [
boundsRef,
containerRef
]);
const handleMouseDown = (event)=>{
event.preventDefault();
setIsDragging(true);
};
const handleMouseMove = (event)=>{
if (!isDragging) return null;
const { x, y } = getCoordinates(event.clientX, event.clientY);
setPosition({
x,
y
});
};
const onDrop = ()=>{
setIsDragging(false);
onDragEnd(position);
};
_react.default.useEffect(()=>{
if (isDragging || !dragRef.current) return;
if (checkBounds) {
const { height, left, top, width } = dragRef.current.getBoundingClientRect();
const { x, y } = getCoordinates(left + width / 2, top + height / 2, true);
onDragEnd({
x,
y
});
setPosition({
x,
y
});
setCheckBounds(false);
return;
}
}, [
getCoordinates,
isDragging,
checkBounds,
setCheckBounds,
position.x,
position.y,
onDragEnd
]);
_react.default.useEffect(()=>{
setPosition({
x: initialPosition.x,
y: initialPosition.y
});
}, [
initialPosition.x,
initialPosition.y
]);
return /*#__PURE__*/ _react.default.createElement("div", {
className: [
`${baseClass}__draggable-container`,
isDragging && `${baseClass}__draggable-container--dragging`
].filter(Boolean).join(' '),
onMouseMove: handleMouseMove
}, /*#__PURE__*/ _react.default.createElement("button", {
className: [
`${baseClass}__draggable`,
className
].filter(Boolean).join(' '),
onMouseDown: handleMouseDown,
onMouseUp: onDrop,
ref: dragRef,
style: {
left: `${position.x}%`,
top: `${position.y}%`
},
type: "button"
}, children), /*#__PURE__*/ _react.default.createElement("div", null));
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9hZG1pbi9jb21wb25lbnRzL2VsZW1lbnRzL0VkaXRVcGxvYWQvaW5kZXgudHN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHVzZU1vZGFsIH0gZnJvbSAnQGZhY2VsZXNzLXVpL21vZGFsJ1xuaW1wb3J0IFJlYWN0LCB7IHVzZVJlZiwgdXNlU3RhdGUgfSBmcm9tICdyZWFjdCdcbmltcG9ydCB7IHVzZVRyYW5zbGF0aW9uIH0gZnJvbSAncmVhY3QtaTE4bmV4dCdcbmltcG9ydCBSZWFjdENyb3AsIHsgdHlwZSBDcm9wIGFzIENyb3BUeXBlIH0gZnJvbSAncmVhY3QtaW1hZ2UtY3JvcCdcbmltcG9ydCAncmVhY3QtaW1hZ2UtY3JvcC9kaXN0L1JlYWN0Q3JvcC5jc3MnXG5cbmltcG9ydCB0eXBlIHsgRGF0YSB9IGZyb20gJy4uLy4uL2Zvcm1zL0Zvcm0vdHlwZXMnXG5cbmltcG9ydCBQbHVzIGZyb20gJy4uLy4uL2ljb25zL1BsdXMnXG5pbXBvcnQgeyB1c2VGb3JtUXVlcnlQYXJhbXMgfSBmcm9tICcuLi8uLi91dGlsaXRpZXMvRm9ybVF1ZXJ5UGFyYW1zJ1xuaW1wb3J0IHsgZWRpdERyYXdlclNsdWcgfSBmcm9tICcuLi8uLi92aWV3cy9jb2xsZWN0aW9ucy9FZGl0L1VwbG9hZCdcbmltcG9ydCBCdXR0b24gZnJvbSAnLi4vQnV0dG9uJ1xuaW1wb3J0ICcuL2luZGV4LnNjc3MnXG5cbmNvbnN0IGJhc2VDbGFzcyA9ICdlZGl0LXVwbG9hZCdcblxuY29uc3QgSW5wdXQ6IFJlYWN0LkZDPHsgbmFtZTogc3RyaW5nOyBvbkNoYW5nZTogKHZhbHVlOiBzdHJpbmcpID0+IHZvaWQ7IHZhbHVlOiBzdHJpbmcgfT4gPSAoe1xuICBuYW1lLFxuICBvbkNoYW5nZSxcbiAgdmFsdWUsXG59KSA9PiAoXG4gIDxkaXYgY2xhc3NOYW1lPXtgJHtiYXNlQ2xhc3N9X19pbnB1dGB9PlxuICAgIHtuYW1lfVxuICAgIDxpbnB1dCBuYW1lPXtuYW1lfSBvbkNoYW5nZT17KGUpID0+IG9uQ2hhbmdlKGUudGFyZ2V0LnZhbHVlKX0gdHlwZT1cIm51bWJlclwiIHZhbHVlPXt2YWx1ZX0gLz5cbiAgPC9kaXY+XG4pXG5cbmV4cG9ydCBjb25zdCBFZGl0VXBsb2FkOiBSZWFjdC5GQzx7XG4gIGRvYz86IERhdGFcbiAgZmlsZU5hbWU6IHN0cmluZ1xuICBmaWxlU3JjOiBzdHJpbmdcbiAgaW1hZ2VDYWNoZVRhZz86IHN0cmluZ1xuICBzaG93Q3JvcD86IGJvb2xlYW5cbiAgc2hvd0ZvY2FsUG9pbnQ/OiBib29sZWFuXG59PiA9ICh7IGZpbGVOYW1lLCBmaWxlU3JjLCBpbWFnZUNhY2hlVGFnLCBzaG93Q3JvcCwgc2hvd0ZvY2FsUG9pbnQgfSkgPT4ge1xuICBjb25zdCB7IGNsb3NlTW9kYWwgfSA9IHVzZU1vZGFsKClcbiAgY29uc3QgeyB0IH0gPSB1c2VUcmFuc2xhdGlvbihbJ2dlbmVyYWwnLCAndXBsb2FkJ10pXG4gIGNvbnN0IHsgZm9ybVF1ZXJ5UGFyYW1zLCBzZXRGb3JtUXVlcnlQYXJhbXMgfSA9IHVzZUZvcm1RdWVyeVBhcmFtcygpXG4gIGNvbnN0IHsgdXBsb2FkRWRpdHMgfSA9IGZvcm1RdWVyeVBhcmFtcyB8fCB7fVxuICBjb25zdCBbY3JvcCwgc2V0Q3JvcF0gPSB1c2VTdGF0ZTxDcm9wVHlwZT4oe1xuICAgIGhlaWdodDogdXBsb2FkRWRpdHM/LmNyb3A/LmhlaWdodCB8fCAxMDAsXG4gICAgdW5pdDogJyUnLFxuICAgIHdpZHRoOiB1cGxvYWRFZGl0cz8uY3JvcD8ud2lkdGggfHwgMTAwLFxuICAgIHg6IHVwbG9hZEVkaXRzPy5jcm9wPy54IHx8IDAsXG4gICAgeTogdXBsb2FkRWRpdHM/LmNyb3A/LnkgfHwgMCxcbiAgfSlcblxuICBjb25zdCBbcG9pbnRQb3NpdGlvbiwgc2V0UG9pbnRQb3NpdGlvbl0gPSB1c2VTdGF0ZTx7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0+KHtcbiAgICB4OiB1cGxvYWRFZGl0cz8uZm9jYWxQb2ludD8ueCB8fCA1MCxcbiAgICB5OiB1cGxvYWRFZGl0cz8uZm9jYWxQb2ludD8ueSB8fCA1MCxcbiAgfSlcbiAgY29uc3QgW2NoZWNrQm91bmRzLCBzZXRDaGVja0JvdW5kc10gPSB1c2VTdGF0ZTxib29sZWFuPihmYWxzZSlcbiAgY29uc3QgW29yaWdpbmFsSGVpZ2h0LCBzZXRPcmlnaW5hbEhlaWdodF0gPSB1c2VTdGF0ZTxudW1iZXI+KDApXG4gIGNvbnN0IFtvcmlnaW5hbFdpZHRoLCBzZXRPcmlnaW5hbFdpZHRoXSA9IHVzZVN0YXRlPG51bWJlcj4oMClcblxuICBjb25zdCBmb2NhbFdyYXBSZWYgPSB1c2VSZWY8SFRNTERpdkVsZW1lbnQgfCB1bmRlZmluZWQ+KClcbiAgY29uc3QgaW1hZ2VSZWYgPSB1c2VSZWY8SFRNTEltYWdlRWxlbWVudCB8IHVuZGVmaW5lZD4oKVxuICBjb25zdCBjcm9wUmVmID0gdXNlUmVmPEhUTUxEaXZFbGVtZW50IHwgdW5kZWZpbmVkPigpXG5cbiAgY29uc3QgZmluZVR1bmVDcm9wID0gKHsgZGltZW5zaW9uLCB2YWx1ZSB9OiB7IGRpbWVuc2lvbjogJ2hlaWdodCcgfCAnd2lkdGgnOyB2YWx1ZTogc3RyaW5nIH0pID0+IHtcbiAgICBjb25zdCBpbnRWYWx1ZSA9IHBhcnNlSW50KHZhbHVlKVxuICAgIGlmIChkaW1lbnNpb24gPT09ICd3aWR0aCcgJiYgaW50VmFsdWUgPj0gb3JpZ2luYWxXaWR0aCkgcmV0dXJuIG51bGxcbiAgICBpZiAoZGltZW5zaW9uID09PSAnaGVpZ2h0JyAmJiBpbnRWYWx1ZSA+PSBvcmlnaW5hbEhlaWdodCkgcmV0dXJuIG51bGxcblxuICAgIGNvbnN0IHBlcmNlbnRhZ2UgPSAxMDAgKiAoaW50VmFsdWUgLyAoZGltZW5zaW9uID09PSAnd2lkdGgnID8gb3JpZ2luYWxXaWR0aCA6IG9yaWdpbmFsSGVpZ2h0KSlcblxuICAgIGlmIChwZXJjZW50YWdlID09PSAxMDAgfHwgcGVyY2VudGFnZSA9PT0gMCkgcmV0dXJuIG51bGxcblxuICAgIHNldENyb3Aoe1xuICAgICAgLi4uY3JvcCxcbiAgICAgIFtkaW1lbnNpb25dOiBwZXJjZW50YWdlLFxuICAgIH0pXG4gIH1cblxuICBjb25zdCBmaW5lVHVuZUZvY2FsUG9pbnQgPSAoeyBjb29yZGluYXRlLCB2YWx1ZSB9OiB7IGNvb3JkaW5hdGU6ICd4JyB8ICd5JzsgdmFsdWU6IHN0cmluZyB9KSA9PiB7XG4gICAgY29uc3QgaW50VmFsdWUgPSBwYXJzZUludCh2YWx1ZSlcbiAgICBpZiAoaW50VmFsdWUgPj0gMCAmJiBpbnRWYWx1ZSA8PSAxMDApIHtcbiAgICAgIHNldFBvaW50UG9zaXRpb24oKHByZXZQb3NpdGlvbikgPT4gKHsgLi4ucHJldlBvc2l0aW9uLCBbY29vcmRpbmF0ZV06IGludFZhbHVlIH0pKVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHNhdmVFZGl0cyA9ICgpID0+IHtcbiAgICBzZXRGb3JtUXVlcnlQYXJhbXMoe1xuICAgICAgLi4uZm9ybVF1ZXJ5UGFyYW1zLFxuICAgICAgdXBsb2FkRWRpdHM6IHtcbiAgICAgICAgY3JvcDogY3JvcCB8fCB1bmRlZmluZWQsXG4gICAgICAgIGZvY2FsUG9pbnQ6IHBvaW50UG9zaXRpb24gPyBwb2ludFBvc2l0aW9uIDogdW5kZWZpbmVkLFxuICAgICAgfSxcbiAgICB9KVxuICAgIGNsb3NlTW9kYWwoZWRpdERyYXdlclNsdWcpXG4gIH1cblxuICBjb25zdCBvbkRyYWdFbmQgPSBSZWFjdC51c2VDYWxsYmFjaygoeyB4LCB5IH0pID0+IHtcbiAgICBzZXRQb2ludFBvc2l0aW9uKHsgeCwgeSB9KVxuICAgIHNldENoZWNrQm91bmRzKGZhbHNlKVxuICB9LCBbXSlcblxuICBjb25zdCBjZW50ZXJGb2NhbFBvaW50ID0gKCkgPT4ge1xuICAgIGNvbnN0IGNvbnRhaW5lclJlY3QgPSBmb2NhbFdyYXBSZWYuY3VycmVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgIGNvbnN0IGJvdW5kc1JlY3QgPSBzaG93Q3JvcFxuICAgICAgPyBjcm9wUmVmLmN1cnJlbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgICAgIDogaW1hZ2VSZWYuY3VycmVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgIGNvbnN0IHhDZW50ZXIgPVxuICAgICAgKChib3VuZHNSZWN0LmxlZnQgLSBjb250YWluZXJSZWN0LmxlZnQgKyBib3VuZHNSZWN0LndpZHRoIC8gMikgLyBjb250YWluZXJSZWN0LndpZHRoKSAqIDEwMFxuICAgIGNvbnN0IHlDZW50ZXIgPVxuICAgICAgKChib3VuZHNSZWN0LnRvcCAtIGNvbnRhaW5lclJlY3QudG9wICsgYm91bmRzUmVjdC5oZWlnaHQgLyAyKSAvIGNvbnRhaW5lclJlY3QuaGVpZ2h0KSAqIDEwMFxuICAgIHNldFBvaW50UG9zaXRpb24oeyB4OiB4Q2VudGVyLCB5OiB5Q2VudGVyIH0pXG4gIH1cblxuICBjb25zdCBmaWxlU3JjVG9Vc2UgPSBpbWFnZUNhY2hlVGFnID8gYCR7ZmlsZVNyY30/JHtpbWFnZUNhY2hlVGFnfWAgOiBmaWxlU3JjXG5cbiAgcmV0dXJuIChcbiAgICA8ZGl2IGNsYXNzTmFtZT17YmFzZUNsYXNzfT5cbiAgICAgIDxkaXYgY2xhc3NOYW1lPXtgJHtiYXNlQ2xhc3N9X19oZWFkZXJgfT5cbiAgICAgICAgPGgyIHRpdGxlPXtgJHt0KCdnZW5lcmFsOmVkaXRpbmcnKX0gJHtmaWxlTmFtZX1gfT5cbiAgICAgICAgICB7dCgnZ2VuZXJhbDplZGl0aW5nJyl9IHtmaWxlTmFtZX1cbiAgICAgICAgPC9oMj5cbiAgICAgICAgPGRpdiBjbGFzc05hbWU9e2Ake2Jhc2VDbGFzc31fX2FjdGlvbnNgfT5cbiAgICAgICAgICA8QnV0dG9uXG4gICAgICAgICAgICBhcmlhLWxhYmVsPXt0KCdjYW5jZWwnKX1cbiAgICAgICAgICAgIGJ1dHRvblN0eWxlPVwic2Vjb25kYXJ5XCJcbiAgICAgICAgICAgIGNsYXNzTmFtZT17YCR7YmFzZUNsYXNzfV9fY2FuY2VsYH1cbiAgICAgICAgICAgIG9uQ2xpY2s9eygpID0+IGNsb3NlTW9kYWwoZWRpdERyYXdlclNsdWcpfVxuICAgICAgICAgID5cbiAgICAgICAgICAgIHt0KCdnZW5lcmFsOmNhbmNlbCcpfVxuICAgICAgICAgIDwvQnV0dG9uPlxuICAgICAgICAgIDxCdXR0b25cbiAgICAgICAgICAgIGFyaWEtbGFiZWw9e3QoJ2dlbmVyYWw6YXBwbHlDaGFuZ2VzJyl9XG4gICAgICAgICAgICBidXR0b25TdHlsZT1cInByaW1hcnlcIlxuICAgICAgICAgICAgY2xhc3NOYW1lPXtgJHtiYXNlQ2xhc3N9X19zYXZlYH1cbiAgICAgICAgICAgIG9uQ2xpY2s9eygpID0+IHNhdmVFZGl0cygpfVxuICAgICAgICAgID5cbiAgICAgICAgICAgIHt0KCdnZW5lcmFsOmFwcGx5Q2hhbmdlcycpfVxuICAgICAgICAgIDwvQnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzc05hbWU9e2Ake2Jhc2VDbGFzc31fX3Rvb2xXcmFwYH0+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPXtgJHtiYXNlQ2xhc3N9X19jcm9wYH0+XG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAgY2xhc3NOYW1lPXtgJHtiYXNlQ2xhc3N9X19mb2NhbC13cmFwcGVyYH1cbiAgICAgICAgICAgIHJlZj17Zm9jYWxXcmFwUmVmfVxuICAgICAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICAgICAgYXNwZWN0UmF0aW86IGAke29yaWdpbmFsV2lkdGggLyBvcmlnaW5hbEhlaWdodH1gLFxuICAgICAgICAgICAgfX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICB7c2hvd0Nyb3AgPyAoXG4gICAgICAgICAgICAgIDxSZWFjdENyb3BcbiAgICAgICAgICAgICAgICBjbGFzc05hbWU9e2Ake2Jhc2VDbGFzc31fX3JlYWN0Q3JvcGB9XG4gICAgICAgICAgICAgICAgY3JvcD17Y3JvcH1cbiAgICAgICAgICAgICAgICBvbkNoYW5nZT17KF8sIGMpID0+IHNldENyb3AoYyl9XG4gICAgICAgICAgICAgICAgb25Db21wbGV0ZT17KCkgPT4gc2V0Q2hlY2tCb3VuZHModHJ1ZSl9XG4gICAgICAgICAgICAgICAgcmVuZGVyU2VsZWN0aW9uQWRkb249eygpID0+IHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiA8ZGl2IGNsYXNzTmFtZT17YCR7YmFzZUNsYXNzfV9fY3JvcC13aW5kb3dgfSByZWY9e2Nyb3BSZWZ9IC8+XG4gICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxpbWdcbiAgICAgICAgICAgICAgICAgIGFsdD17dCgndXBsb2FkOnNldENyb3BBcmVhJyl9XG4gICAgICAgICAgICAgICAgICBvbkxvYWQ9eyhlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHNldE9yaWdpbmFsSGVpZ2h0KGUuY3VycmVudFRhcmdldC5uYXR1cmFsSGVpZ2h0KVxuICAgICAgICAgICAgICAgICAgICBzZXRPcmlnaW5hbFdpZHRoKGUuY3VycmVudFRhcmdldC5uYXR1cmFsV2lkdGgpXG4gICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgICAgcmVmPXtpbWFnZVJlZn1cbiAgICAgICAgICAgICAgICAgIHNyYz17ZmlsZVNyY1RvVXNlfVxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgIDwvUmVhY3RDcm9wPlxuICAgICAgICAgICAgKSA6IChcbiAgICAgICAgICAgICAgPGltZ1xuICAgICAgICAgICAgICAgIGFsdD17dCgndXBsb2FkOnNldEZvY2FsUG9pbnQnKX1cbiAgICAgICAgICAgICAgICBvbkxvYWQ9eyhlKSA9PiB7XG4gICAgICAgICAgICAgICAgICBzZXRPcmlnaW5hbEhlaWdodChlLmN1cnJlbnRUYXJnZXQubmF0dXJhbEhlaWdodClcbiAgICAgICAgICAgICAgICAgIHNldE9yaWdpbmFsV2lkdGgoZS5jdXJyZW50VGFyZ2V0Lm5hdHVyYWxXaWR0aClcbiAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgIHJlZj17aW1hZ2VSZWZ9XG4gICAgICAgICAgICAgICAgc3JjPXtmaWxlU3JjVG9Vc2V9XG4gICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICApfVxuICAgICAgICAgICAge3Nob3dGb2NhbFBvaW50ICYmIChcbiAgICAgICAgICAgICAgPERyYWdnYWJsZUVsZW1lbnRcbiAgICAgICAgICAgICAgICBib3VuZHNSZWY9e3Nob3dDcm9wID8gY3JvcFJlZiA6IGltYWdlUmVmfVxuICAgICAgICAgICAgICAgIGNoZWNrQm91bmRzPXtzaG93Q3JvcCA/IGNoZWNrQm91bmRzIDogZmFsc2V9XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lPXtgJHtiYXNlQ2xhc3N9X19mb2NhbFBvaW50YH1cbiAgICAgICAgICAgICAgICBjb250YWluZXJSZWY9e2ZvY2FsV3JhcFJlZn1cbiAgICAgICAgICAgICAgICBpbml0aWFsUG9zaXRpb249e3BvaW50UG9zaXRpb259XG4gICAgICAgICAgICAgICAgb25EcmFnRW5kPXtvbkRyYWdFbmR9XG4gICAgICAgICAgICAgICAgc2V0Q2hlY2tCb3VuZHM9e3Nob3dDcm9wID8gc2V0Q2hlY2tCb3VuZHMgOiBmYWxzZX1cbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxQbHVzIC8+XG4gICAgICAgICAgICAgIDwvRHJhZ2dhYmxlRWxlbWVudD5cbiAgICAgICAgICAgICl9XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB7KHNob3dDcm9wIHx8IHNob3dGb2NhbFBvaW50KSAmJiAoXG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9e2Ake2Jhc2VDbGFzc31fX3NpZGViYXJgfT5cbiAgICAgICAgICAgIHtzaG93Q3JvcCAmJiAoXG4gICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPXtgJHtiYXNlQ2xhc3N9X19ncm91cFdyYXBgfT5cbiAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9e2Ake2Jhc2VDbGFzc31fX3RpdGxlV3JhcGB9PlxuICAgICAgICAgICAgICAgICAgICA8aDM+e3QoJ3VwbG9hZDpjcm9wJyl9PC9oMz5cbiAgICAgICAgICAgICAgICAgICAgPEJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgIGJ1dHRvblN0eWxlPVwibm9uZVwiXG4gICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPXtgJHtiYXNlQ2xhc3N9X19yZXNldGB9XG4gICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17KCkgPT5cbiAgICAgICAgICAgICAgICAgICAgICAgIHNldENyb3Aoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IDEwMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdDogJyUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogMTAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICB4OiAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICB5OiAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICB7dCgnZ2VuZXJhbDpyZXNldCcpfVxuICAgICAgICAgICAgICAgICAgICA8L0J1dHRvbj5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT17YCR7YmFzZUNsYXNzfV9fZGVzY3JpcHRpb25gfT5cbiAgICAgICAgICAgICAgICAgIHt0KCd1cGxvYWQ6Y3JvcFRvb2xEZXNjcmlwdGlvbicpfVxuICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT17YCR7YmFzZUNsYXNzfV9faW5wdXRzV3JhcGB9PlxuICAgICAgICAgICAgICAgICAgPElucHV0XG4gICAgICAgICAgICAgICAgICAgIG5hbWU9e2Ake3QoJ3VwbG9hZDp3aWR0aCcpfSAocHgpYH1cbiAgICAgICAgICAgICAgICAgICAgb25DaGFuZ2U9eyh2YWx1ZSkgPT4gZmluZVR1bmVDcm9wKHsgZGltZW5zaW9uOiAnd2lkdGgnLCB2YWx1ZSB9KX1cbiAgICAgICAgICAgICAgICAgICAgdmFsdWU9eygoY3JvcC53aWR0aCAvIDEwMCkgKiBvcmlnaW5hbFdpZHRoKS50b0ZpeGVkKDApfVxuICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgIDxJbnB1dFxuICAgICAgICAgICAgICAgICAgICBuYW1lPXtgJHt0KCd1cGxvYWQ6aGVpZ2h0Jyl9IChweClgfVxuICAgICAgICAgICAgICAgICAgICBvbkNoYW5nZT17KHZhbHVlKSA9PiBmaW5lVHVuZUNyb3AoeyBkaW1lbnNpb246ICdoZWlnaHQnLCB2YWx1ZSB9KX1cbiAgICAgICAgICAgICAgICAgICAgdmFsdWU9eygoY3JvcC5oZWlnaHQgLyAxMDApICogb3JpZ2luYWxIZWlnaHQpLnRvRml4ZWQoMCl9XG4gICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICl9XG5cbiAgICAgICAgICAgIHtzaG93Rm9jYWxQb2ludCAmJiAoXG4gICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPXtgJHtiYXNlQ2xhc3N9X19ncm91cFdyYXBgfT5cbiAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9e2Ake2Jhc2VDbGFzc31fX3RpdGxlV3JhcGB9PlxuICAgICAgICAgICAgICAgICAgICA8aDM+e3QoJ3VwbG9hZDpmb2NhbFBvaW50Jyl9PC9oMz5cbiAgICAgICAgICAgICAgICAgICAgPEJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgIGJ1dHRvblN0eWxlPVwibm9uZVwiXG4gICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPXtgJHtiYXNlQ2xhc3N9X19yZXNldGB9XG4gICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17Y2VudGVyRm9jYWxQb2ludH1cbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgIHt0KCdnZW5lcmFsOnJlc2V0Jyl9XG4gICAgICAgICAgICAgICAgICAgIDwvQnV0dG9uPlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPXtgJHtiYXNlQ2xhc3N9X19kZXNjcmlwdGlvbmB9PlxuICAgICAgICAgICAgICAgICAge3QoJ3VwbG9hZDpmb2NhbFBvaW50RGVzY3JpcHRpb24nKX1cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9e2Ake2Jhc2VDbGFzc31fX2lucHV0c1dyYXBgfT5cbiAgICAgICAgICAgICAgICAgIDxJbnB1dFxuICAgICAgICAgICAgICAgICAgICBuYW1lPVwiWCAlXCJcbiAgICAgICAgICAgICAgICAgICAgb25DaGFuZ2U9eyh2YWx1ZSkgPT4gZmluZVR1bmVGb2NhbFBvaW50KHsgY29vcmRpbmF0ZTogJ3gnLCB2YWx1ZSB9KX1cbiAgICAgICAgICAgICAgICAgICAgdmFsdWU9e3BvaW50UG9zaXRpb24ueC50b0ZpeGVkKDApfVxuICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgIDxJbnB1dFxuICAgICAgICAgICAgICAgICAgICBuYW1lPVwiWSAlXCJcbiAgICAgICAgICAgICAgICAgICAgb25DaGFuZ2U9eyh2YWx1ZSkgPT4gZmluZVR1bmVGb2NhbFBvaW50KHsgY29vcmRpbmF0ZTogJ3knLCB2YWx1ZSB9KX1cbiAgICAgICAgICAgICAgICAgICAgdmFsdWU9e3BvaW50UG9zaXRpb24ueS50b0ZpeGVkKDApfVxuICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICApfVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICApfVxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIClcbn1cblxuY29uc3QgRHJhZ2dhYmxlRWxlbWVudCA9ICh7XG4gIGJvdW5kc1JlZixcbiAgY2hlY2tCb3VuZHMsXG4gIGNoaWxkcmVuLFxuICBjbGFzc05hbWUsXG4gIGNvbnRhaW5lclJlZixcbiAgaW5pdGlhbFBvc2l0aW9uID0geyB4OiA1MCwgeTogNTAgfSxcbiAgb25EcmFnRW5kLFxuICBzZXRDaGVja0JvdW5kcyxcbn0pID0+IHtcbiAgY29uc3QgW3Bvc2l0aW9uLCBzZXRQb3NpdGlvbl0gPSB1c2VTdGF0ZSh7IHg6IGluaXRpYWxQb3NpdGlvbi54LCB5OiBpbml0aWFsUG9zaXRpb24ueSB9KVxuICBjb25zdCBbaXNEcmFnZ2luZywgc2V0SXNEcmFnZ2luZ10gPSB1c2VTdGF0ZShmYWxzZSlcbiAgY29uc3QgZHJhZ1JlZiA9IHVzZVJlZjxIVE1MQnV0dG9uRWxlbWVudCB8IHVuZGVmaW5lZD4oKVxuXG4gIGNvbnN0IGdldENvb3JkaW5hdGVzID0gUmVhY3QudXNlQ2FsbGJhY2soXG4gICAgKG1vdXNlWEFyZz86IG51bWJlciwgbW91c2VZQXJnPzogbnVtYmVyLCByZWNlbnRlcj86IGJvb2xlYW4pID0+IHtcbiAgICAgIGNvbnN0IGNvbnRhaW5lclJlY3QgPSBjb250YWluZXJSZWYuY3VycmVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgICAgY29uc3QgYm91bmRzUmVjdCA9IGJvdW5kc1JlZi5jdXJyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG4gICAgICBjb25zdCBtb3VzZVggPSBtb3VzZVhBcmcgPz8gYm91bmRzUmVjdC5sZWZ0XG4gICAgICBjb25zdCBtb3VzZVkgPSBtb3VzZVlBcmcgPz8gYm91bmRzUmVjdC50b3BcblxuICAgICAgY29uc3QgeE91dE9mQm91bmRzID0gbW91c2VYIDwgYm91bmRzUmVjdC5sZWZ0IHx8IG1vdXNlWCA+IGJvdW5kc1JlY3QucmlnaHRcbiAgICAgIGNvbnN0IHlPdXRPZkJvdW5kcyA9IG1vdXNlWSA8IGJvdW5kc1JlY3QudG9wIHx8IG1vdXNlWSA+IGJvdW5kc1JlY3QuYm90dG9tXG5cbiAgICAgIGxldCB4ID0gKChtb3VzZVggLSBjb250YWluZXJSZWN0LmxlZnQpIC8gY29udGFpbmVyUmVjdC53aWR0aCkgKiAxMDBcbiAgICAgIGxldCB5ID0gKChtb3VzZVkgLSBjb250YWluZXJSZWN0LnRvcCkgLyBjb250YWluZXJSZWN0LmhlaWdodCkgKiAxMDBcbiAgICAgIGNvbnN0IHhDZW50ZXIgPVxuICAgICAgICAoKGJvdW5kc1JlY3QubGVmdCAtIGNvbnRhaW5lclJlY3QubGVmdCArIGJvdW5kc1JlY3Qud2lkdGggLyAyKSAvIGNvbnRhaW5lclJlY3Qud2lkdGgpICogMTAwXG4gICAgICBjb25zdCB5Q2VudGVyID1cbiAgICAgICAgKChib3VuZHNSZWN0LnRvcCAtIGNvbnRhaW5lclJlY3QudG9wICsgYm91bmRzUmVjdC5oZWlnaHQgLyAyKSAvIGNvbnRhaW5lclJlY3QuaGVpZ2h0KSAqIDEwMFxuICAgICAgaWYgKHhPdXRPZkJvdW5kcyB8fCB5T3V0T2ZCb3VuZHMpIHtcbiAgICAgICAgc2V0SXNEcmFnZ2luZyhmYWxzZSlcbiAgICAgICAgaWYgKG1vdXNlWCA8IGJvdW5kc1JlY3QubGVmdCkge1xuICAgICAgICAgIHggPSAoKGJvdW5kc1JlY3QubGVmdCAtIGNvbnRhaW5lclJlY3QubGVmdCkgLyBjb250YWluZXJSZWN0LndpZHRoKSAqIDEwMFxuICAgICAgICB9IGVsc2UgaWYgKG1vdXNlWCA+IGJvdW5kc1JlY3QucmlnaHQpIHtcbiAgICAgICAgICB4ID1cbiAgICAgICAgICAgICgoY29udGFpbmVyUmVjdC53aWR0aCAtIChjb250YWluZXJSZWN0LnJpZ2h0IC0gYm91bmRzUmVjdC5yaWdodCkpIC9cbiAgICAgICAgICAgICAgY29udGFpbmVyUmVjdC53aWR0aCkgKlxuICAgICAgICAgICAgMTAwXG4gICAgICAgIH1cblxuICAgICAgICBpZiAobW91c2VZIDwgYm91bmRzUmVjdC50b3ApIHtcbiAgICAgICAgICB5ID0gKChib3VuZHNSZWN0LnRvcCAtIGNvbnRhaW5lclJlY3QudG9wKSAvIGNvbnRhaW5lclJlY3QuaGVpZ2h0KSAqIDEwMFxuICAgICAgICB9IGVsc2UgaWYgKG1vdXNlWSA+IGJvdW5kc1JlY3QuYm90dG9tKSB7XG4gICAgICAgICAgeSA9XG4gICAgICAgICAgICAoKGNvbnRhaW5lclJlY3QuaGVpZ2h0IC0gKGNvbnRhaW5lclJlY3QuYm90dG9tIC0gYm91bmRzUmVjdC5ib3R0b20pKSAvXG4gICAgICAgICAgICAgIGNvbnRhaW5lclJlY3QuaGVpZ2h0KSAqXG4gICAgICAgICAgICAxMDBcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChyZWNlbnRlcikge1xuICAgICAgICAgIHggPSB4T3V0T2ZCb3VuZHMgPyB4Q2VudGVyIDogeFxuICAgICAgICAgIHkgPSB5T3V0T2ZCb3VuZHMgPyB5Q2VudGVyIDogeVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7IHgsIHkgfVxuICAgIH0sXG4gICAgW2JvdW5kc1JlZiwgY29udGFpbmVyUmVmXSxcbiAgKVxuXG4gIGNvbnN0IGhhbmRsZU1vdXNlRG93biA9IChldmVudCkgPT4ge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KClcbiAgICBzZXRJc0RyYWdnaW5nKHRydWUpXG4gIH1cblxuICBjb25zdCBoYW5kbGVNb3VzZU1vdmUgPSAoZXZlbnQpID0+IHtcbiAgICBpZiAoIWlzRHJhZ2dpbmcpIHJldHVybiBudWxsXG4gICAgY29uc3QgeyB4LCB5IH0gPSBnZXRDb29yZGluYXRlcyhldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZKVxuXG4gICAgc2V0UG9zaXRpb24oeyB4LCB5IH0pXG4gIH1cblxuICBjb25zdCBvbkRyb3AgPSAoKSA9PiB7XG4gICAgc2V0SXNEcmFnZ2luZyhmYWxzZSlcbiAgICBvbkRyYWdFbmQocG9zaXRpb24pXG4gIH1cblxuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChpc0RyYWdnaW5nIHx8ICFkcmFnUmVmLmN1cnJlbnQpIHJldHVyblxuICAgIGlmIChjaGVja0JvdW5kcykge1xuICAgICAgY29uc3QgeyBoZWlnaHQsIGxlZnQsIHRvcCwgd2lkdGggfSA9IGRyYWdSZWYuY3VycmVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgICAgY29uc3QgeyB4LCB5IH0gPSBnZXRDb29yZGluYXRlcyhsZWZ0ICsgd2lkdGggLyAyLCB0b3AgKyBoZWlnaHQgLyAyLCB0cnVlKVxuICAgICAgb25EcmFnRW5kKHsgeCwgeSB9KVxuICAgICAgc2V0UG9zaXRpb24oeyB4LCB5IH0pXG4gICAgICBzZXRDaGVja0JvdW5kcyhmYWxzZSlcbiAgICAgIHJldHVyblxuICAgIH1cbiAgfSwgW2dldENvb3JkaW5hdGVzLCBpc0RyYWdnaW5nLCBjaGVja0JvdW5kcywgc2V0Q2hlY2tCb3VuZHMsIHBvc2l0aW9uLngsIHBvc2l0aW9uLnksIG9uRHJhZ0VuZF0pXG5cbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBzZXRQb3NpdGlvbih7IHg6IGluaXRpYWxQb3NpdGlvbi54LCB5OiBpbml0aWFsUG9zaXRpb24ueSB9KVxuICB9LCBbaW5pdGlhbFBvc2l0aW9uLngsIGluaXRpYWxQb3NpdGlvbi55XSlcblxuICByZXR1cm4gKFxuICAgIDxkaXZcbiAgICAgIGNsYXNzTmFtZT17W1xuICAgICAgICBgJHtiYXNlQ2xhc3N9X19kcmFnZ2FibGUtY29udGFpbmVyYCxcbiAgICAgICAgaXNEcmFnZ2luZyAmJiBgJHtiYXNlQ2xhc3N9X19kcmFnZ2FibGUtY29udGFpbmVyLS1kcmFnZ2luZ2AsXG4gICAgICBdXG4gICAgICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAgICAgLmpvaW4oJyAnKX1cbiAgICAgIG9uTW91c2VNb3ZlPXtoYW5kbGVNb3VzZU1vdmV9XG4gICAgPlxuICAgICAgPGJ1dHRvblxuICAgICAgICBjbGFzc05hbWU9e1tgJHtiYXNlQ2xhc3N9X19kcmFnZ2FibGVgLCBjbGFzc05hbWVdLmZpbHRlcihCb29sZWFuKS5qb2luKCcgJyl9XG4gICAgICAgIG9uTW91c2VEb3duPXtoYW5kbGVNb3VzZURvd259XG4gICAgICAgIG9uTW91c2VVcD17b25Ecm9wfVxuICAgICAgICByZWY9e2RyYWdSZWZ9XG4gICAgICAgIHN0eWxlPXt7IGxlZnQ6IGAke3Bvc2l0aW9uLnh9JWAsIHRvcDogYCR7cG9zaXRpb24ueX0lYCB9fVxuICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgID5cbiAgICAgICAge2NoaWxkcmVufVxuICAgICAgPC9idXR0b24+XG4gICAgICA8ZGl2IC8+XG4gICAgPC9kaXY+XG4gIClcbn1cbiJdLCJuYW1lcyI6WyJFZGl0VXBsb2FkIiwiYmFzZUNsYXNzIiwiSW5wdXQiLCJuYW1lIiwib25DaGFuZ2UiLCJ2YWx1ZSIsImRpdiIsImNsYXNzTmFtZSIsImlucHV0IiwiZSIsInRhcmdldCIsInR5cGUiLCJmaWxlTmFtZSIsImZpbGVTcmMiLCJpbWFnZUNhY2hlVGFnIiwic2hvd0Nyb3AiLCJzaG93Rm9jYWxQb2ludCIsImNsb3NlTW9kYWwiLCJ1c2VNb2RhbCIsInQiLCJ1c2VUcmFuc2xhdGlvbiIsImZvcm1RdWVyeVBhcmFtcyIsInNldEZvcm1RdWVyeVBhcmFtcyIsInVzZUZvcm1RdWVyeVBhcmFtcyIsInVwbG9hZEVkaXRzIiwiY3JvcCIsInNldENyb3AiLCJ1c2VTdGF0ZSIsImhlaWdodCIsInVuaXQiLCJ3aWR0aCIsIngiLCJ5IiwicG9pbnRQb3NpdGlvbiIsInNldFBvaW50UG9zaXRpb24iLCJmb2NhbFBvaW50IiwiY2hlY2tCb3VuZHMiLCJzZXRDaGVja0JvdW5kcyIsIm9yaWdpbmFsSGVpZ2h0Iiwic2V0T3JpZ2luYWxIZWlnaHQiLCJvcmlnaW5hbFdpZHRoIiwic2V0T3JpZ2luYWxXaWR0aCIsImZvY2FsV3JhcFJlZiIsInVzZVJlZiIsImltYWdlUmVmIiwiY3JvcFJlZiIsImZpbmVUdW5lQ3JvcCIsImRpbWVuc2lvbiIsImludFZhbHVlIiwicGFyc2VJbnQiLCJwZXJjZW50YWdlIiwiZmluZVR1bmVGb2NhbFBvaW50IiwiY29vcmRpbmF0ZSIsInByZXZQb3NpdGlvbiIsInNhdmVFZGl0cyIsInVuZGVmaW5lZCIsImVkaXREcmF3ZXJTbHVnIiwib25EcmFnRW5kIiwiUmVhY3QiLCJ1c2VDYWxsYmFjayIsImNlbnRlckZvY2FsUG9pbnQiLCJjb250YWluZXJSZWN0IiwiY3VycmVudCIsImdldEJvdW5kaW5nQ2xpZW50UmVjdCIsImJvdW5kc1JlY3QiLCJ4Q2VudGVyIiwibGVmdCIsInlDZW50ZXIiLCJ0b3AiLCJmaWxlU3JjVG9Vc2UiLCJoMiIsInRpdGxlIiwiQnV0dG9uIiwiYXJpYS1sYWJlbCIsImJ1dHRvblN0eWxlIiwib25DbGljayIsInJlZiIsInN0eWxlIiwiYXNwZWN0UmF0aW8iLCJSZWFjdENyb3AiLCJfIiwiYyIsIm9uQ29tcGxldGUiLCJyZW5kZXJTZWxlY3Rpb25BZGRvbiIsImltZyIsImFsdCIsIm9uTG9hZCIsImN1cnJlbnRUYXJnZXQiLCJuYXR1cmFsSGVpZ2h0IiwibmF0dXJhbFdpZHRoIiwic3JjIiwiRHJhZ2dhYmxlRWxlbWVudCIsImJvdW5kc1JlZiIsImNvbnRhaW5lclJlZiIsImluaXRpYWxQb3NpdGlvbiIsIlBsdXMiLCJoMyIsInNwYW4iLCJ0b0ZpeGVkIiwiY2hpbGRyZW4iLCJwb3NpdGlvbiIsInNldFBvc2l0aW9uIiwiaXNEcmFnZ2luZyIsInNldElzRHJhZ2dpbmciLCJkcmFnUmVmIiwiZ2V0Q29vcmRpbmF0ZXMiLCJtb3VzZVhBcmciLCJtb3VzZVlBcmciLCJyZWNlbnRlciIsIm1vdXNlWCIsIm1vdXNlWSIsInhPdXRPZkJvdW5kcyIsInJpZ2h0IiwieU91dE9mQm91bmRzIiwiYm90dG9tIiwiaGFuZGxlTW91c2VEb3duIiwiZXZlbnQiLCJwcmV2ZW50RGVmYXVsdCIsImhhbmRsZU1vdXNlTW92ZSIsImNsaWVudFgiLCJjbGllbnRZIiwib25Ecm9wIiwidXNlRWZmZWN0IiwiZmlsdGVyIiwiQm9vbGVhbiIsImpvaW4iLCJvbk1vdXNlTW92ZSIsImJ1dHRvbiIsIm9uTW91c2VEb3duIiwib25Nb3VzZVVwIl0sIm1hcHBpbmdzIjoiOzs7OytCQTJCYUE7OztlQUFBQTs7O3VCQTNCWTsrREFDZTs4QkFDVDt1RUFDa0I7UUFDMUM7NkRBSVU7aUNBQ2tCO3dCQUNKOytEQUNaO1FBQ1o7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRVAsTUFBTUMsWUFBWTtBQUVsQixNQUFNQyxRQUFzRixDQUFDLEVBQzNGQyxJQUFJLEVBQ0pDLFFBQVEsRUFDUkMsS0FBSyxFQUNOLGlCQUNDLDZCQUFDQztRQUFJQyxXQUFXLENBQUMsRUFBRU4sVUFBVSxPQUFPLENBQUM7T0FDbENFLG9CQUNELDZCQUFDSztRQUFNTCxNQUFNQTtRQUFNQyxVQUFVLENBQUNLLElBQU1MLFNBQVNLLEVBQUVDLE1BQU0sQ0FBQ0wsS0FBSztRQUFHTSxNQUFLO1FBQVNOLE9BQU9BOztBQUloRixNQUFNTCxhQU9SLENBQUMsRUFBRVksUUFBUSxFQUFFQyxPQUFPLEVBQUVDLGFBQWEsRUFBRUMsUUFBUSxFQUFFQyxjQUFjLEVBQUU7SUFDbEUsTUFBTSxFQUFFQyxVQUFVLEVBQUUsR0FBR0MsSUFBQUEsZUFBUTtJQUMvQixNQUFNLEVBQUVDLENBQUMsRUFBRSxHQUFHQyxJQUFBQSw0QkFBYyxFQUFDO1FBQUM7UUFBVztLQUFTO0lBQ2xELE1BQU0sRUFBRUMsZUFBZSxFQUFFQyxrQkFBa0IsRUFBRSxHQUFHQyxJQUFBQSxtQ0FBa0I7SUFDbEUsTUFBTSxFQUFFQyxXQUFXLEVBQUUsR0FBR0gsbUJBQW1CLENBQUM7SUFDNUMsTUFBTSxDQUFDSSxNQUFNQyxRQUFRLEdBQUdDLElBQUFBLGVBQVEsRUFBVztRQUN6Q0MsUUFBUUosYUFBYUMsTUFBTUcsVUFBVTtRQUNyQ0MsTUFBTTtRQUNOQyxPQUFPTixhQUFhQyxNQUFNSyxTQUFTO1FBQ25DQyxHQUFHUCxhQUFhQyxNQUFNTSxLQUFLO1FBQzNCQyxHQUFHUixhQUFhQyxNQUFNTyxLQUFLO0lBQzdCO0lBRUEsTUFBTSxDQUFDQyxlQUFlQyxpQkFBaUIsR0FBR1AsSUFBQUEsZUFBUSxFQUEyQjtRQUMzRUksR0FBR1AsYUFBYVcsWUFBWUosS0FBSztRQUNqQ0MsR0FBR1IsYUFBYVcsWUFBWUgsS0FBSztJQUNuQztJQUNBLE1BQU0sQ0FBQ0ksYUFBYUMsZUFBZSxHQUFHVixJQUFBQSxlQUFRLEVBQVU7SUFDeEQsTUFBTSxDQUFDVyxnQkFBZ0JDLGtCQUFrQixHQUFHWixJQUFBQSxlQUFRLEVBQVM7SUFDN0QsTUFBTSxDQUFDYSxlQUFlQyxpQkFBaUIsR0FBR2QsSUFBQUEsZUFBUSxFQUFTO0lBRTNELE1BQU1lLGVBQWVDLElBQUFBLGFBQU07SUFDM0IsTUFBTUMsV0FBV0QsSUFBQUEsYUFBTTtJQUN2QixNQUFNRSxVQUFVRixJQUFBQSxhQUFNO0lBRXRCLE1BQU1HLGVBQWUsQ0FBQyxFQUFFQyxTQUFTLEVBQUUxQyxLQUFLLEVBQW9EO1FBQzFGLE1BQU0yQyxXQUFXQyxTQUFTNUM7UUFDMUIsSUFBSTBDLGNBQWMsV0FBV0MsWUFBWVIsZUFBZSxPQUFPO1FBQy9ELElBQUlPLGNBQWMsWUFBWUMsWUFBWVYsZ0JBQWdCLE9BQU87UUFFakUsTUFBTVksYUFBYSxNQUFPRixDQUFBQSxXQUFZRCxDQUFBQSxjQUFjLFVBQVVQLGdCQUFnQkYsY0FBYSxDQUFDO1FBRTVGLElBQUlZLGVBQWUsT0FBT0EsZUFBZSxHQUFHLE9BQU87UUFFbkR4QixRQUFRO1lBQ04sR0FBR0QsSUFBSTtZQUNQLENBQUNzQixVQUFVLEVBQUVHO1FBQ2Y7SUFDRjtJQUVBLE1BQU1DLHFCQUFxQixDQUFDLEVBQUVDLFVBQVUsRUFBRS9DLEtBQUssRUFBNEM7UUFDekYsTUFBTTJDLFdBQVdDLFNBQVM1QztRQUMxQixJQUFJMkMsWUFBWSxLQUFLQSxZQUFZLEtBQUs7WUFDcENkLGlCQUFpQixDQUFDbUIsZUFBa0IsQ0FBQTtvQkFBRSxHQUFHQSxZQUFZO29CQUFFLENBQUNELFdBQVcsRUFBRUo7Z0JBQVMsQ0FBQTtRQUNoRjtJQUNGO0lBRUEsTUFBTU0sWUFBWTtRQUNoQmhDLG1CQUFtQjtZQUNqQixHQUFHRCxlQUFlO1lBQ2xCRyxhQUFhO2dCQUNYQyxNQUFNQSxRQUFROEI7Z0JBQ2RwQixZQUFZRixnQkFBZ0JBLGdCQUFnQnNCO1lBQzlDO1FBQ0Y7UUFDQXRDLFdBQVd1QyxzQkFBYztJQUMzQjtJQUVBLE1BQU1DLFlBQVlDLGNBQUssQ0FBQ0MsV0FBVyxDQUFDLENBQUMsRUFBRTVCLENBQUMsRUFBRUMsQ0FBQyxFQUFFO1FBQzNDRSxpQkFBaUI7WUFBRUg7WUFBR0M7UUFBRTtRQUN4QkssZUFBZTtJQUNqQixHQUFHLEVBQUU7SUFFTCxNQUFNdUIsbUJBQW1CO1FBQ3ZCLE1BQU1DLGdCQUFnQm5CLGFBQWFvQixPQUFPLENBQUNDLHFCQUFxQjtRQUNoRSxNQUFNQyxhQUFhakQsV0FDZjhCLFFBQVFpQixPQUFPLENBQUNDLHFCQUFxQixLQUNyQ25CLFNBQVNrQixPQUFPLENBQUNDLHFCQUFxQjtRQUMxQyxNQUFNRSxVQUNKLEFBQUVELENBQUFBLFdBQVdFLElBQUksR0FBR0wsY0FBY0ssSUFBSSxHQUFHRixXQUFXbEMsS0FBSyxHQUFHLENBQUEsSUFBSytCLGNBQWMvQixLQUFLLEdBQUk7UUFDMUYsTUFBTXFDLFVBQ0osQUFBRUgsQ0FBQUEsV0FBV0ksR0FBRyxHQUFHUCxjQUFjTyxHQUFHLEdBQUdKLFdBQVdwQyxNQUFNLEdBQUcsQ0FBQSxJQUFLaUMsY0FBY2pDLE1BQU0sR0FBSTtRQUMxRk0saUJBQWlCO1lBQUVILEdBQUdrQztZQUFTakMsR0FBR21DO1FBQVE7SUFDNUM7SUFFQSxNQUFNRSxlQUFldkQsZ0JBQWdCLENBQUMsRUFBRUQsUUFBUSxDQUFDLEVBQUVDLGNBQWMsQ0FBQyxHQUFHRDtJQUVyRSxxQkFDRSw2QkFBQ1A7UUFBSUMsV0FBV047cUJBQ2QsNkJBQUNLO1FBQUlDLFdBQVcsQ0FBQyxFQUFFTixVQUFVLFFBQVEsQ0FBQztxQkFDcEMsNkJBQUNxRTtRQUFHQyxPQUFPLENBQUMsRUFBRXBELEVBQUUsbUJBQW1CLENBQUMsRUFBRVAsU0FBUyxDQUFDO09BQzdDTyxFQUFFLG9CQUFtQixLQUFFUCx5QkFFMUIsNkJBQUNOO1FBQUlDLFdBQVcsQ0FBQyxFQUFFTixVQUFVLFNBQVMsQ0FBQztxQkFDckMsNkJBQUN1RSxlQUFNO1FBQ0xDLGNBQVl0RCxFQUFFO1FBQ2R1RCxhQUFZO1FBQ1puRSxXQUFXLENBQUMsRUFBRU4sVUFBVSxRQUFRLENBQUM7UUFDakMwRSxTQUFTLElBQU0xRCxXQUFXdUMsc0JBQWM7T0FFdkNyQyxFQUFFLGtDQUVMLDZCQUFDcUQsZUFBTTtRQUNMQyxjQUFZdEQsRUFBRTtRQUNkdUQsYUFBWTtRQUNabkUsV0FBVyxDQUFDLEVBQUVOLFVBQVUsTUFBTSxDQUFDO1FBQy9CMEUsU0FBUyxJQUFNckI7T0FFZG5DLEVBQUUsMENBSVQsNkJBQUNiO1FBQUlDLFdBQVcsQ0FBQyxFQUFFTixVQUFVLFVBQVUsQ0FBQztxQkFDdEMsNkJBQUNLO1FBQUlDLFdBQVcsQ0FBQyxFQUFFTixVQUFVLE1BQU0sQ0FBQztxQkFDbEMsNkJBQUNLO1FBQ0NDLFdBQVcsQ0FBQyxFQUFFTixVQUFVLGVBQWUsQ0FBQztRQUN4QzJFLEtBQUtsQztRQUNMbUMsT0FBTztZQUNMQyxhQUFhLENBQUMsRUFBRXRDLGdCQUFnQkYsZUFBZSxDQUFDO1FBQ2xEO09BRUN2Qix5QkFDQyw2QkFBQ2dFLHVCQUFTO1FBQ1J4RSxXQUFXLENBQUMsRUFBRU4sVUFBVSxXQUFXLENBQUM7UUFDcEN3QixNQUFNQTtRQUNOckIsVUFBVSxDQUFDNEUsR0FBR0MsSUFBTXZELFFBQVF1RDtRQUM1QkMsWUFBWSxJQUFNN0MsZUFBZTtRQUNqQzhDLHNCQUFzQjtZQUNwQixxQkFBTyw2QkFBQzdFO2dCQUFJQyxXQUFXLENBQUMsRUFBRU4sVUFBVSxhQUFhLENBQUM7Z0JBQUUyRSxLQUFLL0I7O1FBQzNEO3FCQUVBLDZCQUFDdUM7UUFDQ0MsS0FBS2xFLEVBQUU7UUFDUG1FLFFBQVEsQ0FBQzdFO1lBQ1A4QixrQkFBa0I5QixFQUFFOEUsYUFBYSxDQUFDQyxhQUFhO1lBQy9DL0MsaUJBQWlCaEMsRUFBRThFLGFBQWEsQ0FBQ0UsWUFBWTtRQUMvQztRQUNBYixLQUFLaEM7UUFDTDhDLEtBQUtyQjt3QkFJVCw2QkFBQ2U7UUFDQ0MsS0FBS2xFLEVBQUU7UUFDUG1FLFFBQVEsQ0FBQzdFO1lBQ1A4QixrQkFBa0I5QixFQUFFOEUsYUFBYSxDQUFDQyxhQUFhO1lBQy9DL0MsaUJBQWlCaEMsRUFBRThFLGFBQWEsQ0FBQ0UsWUFBWTtRQUMvQztRQUNBYixLQUFLaEM7UUFDTDhDLEtBQUtyQjtRQUdSckQsZ0NBQ0MsNkJBQUMyRTtRQUNDQyxXQUFXN0UsV0FBVzhCLFVBQVVEO1FBQ2hDUixhQUFhckIsV0FBV3FCLGNBQWM7UUFDdEM3QixXQUFXLENBQUMsRUFBRU4sVUFBVSxZQUFZLENBQUM7UUFDckM0RixjQUFjbkQ7UUFDZG9ELGlCQUFpQjdEO1FBQ2pCd0IsV0FBV0E7UUFDWHBCLGdCQUFnQnRCLFdBQVdzQixpQkFBaUI7cUJBRTVDLDZCQUFDMEQsYUFBSSxZQUtaLEFBQUNoRixDQUFBQSxZQUFZQyxjQUFhLG1CQUN6Qiw2QkFBQ1Y7UUFBSUMsV0FBVyxDQUFDLEVBQUVOLFVBQVUsU0FBUyxDQUFDO09BQ3BDYywwQkFDQyw2QkFBQ1Q7UUFBSUMsV0FBVyxDQUFDLEVBQUVOLFVBQVUsV0FBVyxDQUFDO3FCQUN2Qyw2QkFBQ0ssMkJBQ0MsNkJBQUNBO1FBQUlDLFdBQVcsQ0FBQyxFQUFFTixVQUFVLFdBQVcsQ0FBQztxQkFDdkMsNkJBQUMrRixZQUFJN0UsRUFBRSwrQkFDUCw2QkFBQ3FELGVBQU07UUFDTEUsYUFBWTtRQUNabkUsV0FBVyxDQUFDLEVBQUVOLFVBQVUsT0FBTyxDQUFDO1FBQ2hDMEUsU0FBUyxJQUNQakQsUUFBUTtnQkFDTkUsUUFBUTtnQkFDUkMsTUFBTTtnQkFDTkMsT0FBTztnQkFDUEMsR0FBRztnQkFDSEMsR0FBRztZQUNMO09BR0RiLEVBQUUsbUNBSVQsNkJBQUM4RTtRQUFLMUYsV0FBVyxDQUFDLEVBQUVOLFVBQVUsYUFBYSxDQUFDO09BQ3pDa0IsRUFBRSw4Q0FFTCw2QkFBQ2I7UUFBSUMsV0FBVyxDQUFDLEVBQUVOLFVBQVUsWUFBWSxDQUFDO3FCQUN4Qyw2QkFBQ0M7UUFDQ0MsTUFBTSxDQUFDLEVBQUVnQixFQUFFLGdCQUFnQixLQUFLLENBQUM7UUFDakNmLFVBQVUsQ0FBQ0MsUUFBVXlDLGFBQWE7Z0JBQUVDLFdBQVc7Z0JBQVMxQztZQUFNO1FBQzlEQSxPQUFPLEFBQUMsQ0FBQSxBQUFDb0IsS0FBS0ssS0FBSyxHQUFHLE1BQU9VLGFBQVksRUFBRzBELE9BQU8sQ0FBQztzQkFFdEQsNkJBQUNoRztRQUNDQyxNQUFNLENBQUMsRUFBRWdCLEVBQUUsaUJBQWlCLEtBQUssQ0FBQztRQUNsQ2YsVUFBVSxDQUFDQyxRQUFVeUMsYUFBYTtnQkFBRUMsV0FBVztnQkFBVTFDO1lBQU07UUFDL0RBLE9BQU8sQUFBQyxDQUFBLEFBQUNvQixLQUFLRyxNQUFNLEdBQUcsTUFBT1UsY0FBYSxFQUFHNEQsT0FBTyxDQUFDO1VBTTdEbEYsZ0NBQ0MsNkJBQUNWO1FBQUlDLFdBQVcsQ0FBQyxFQUFFTixVQUFVLFdBQVcsQ0FBQztxQkFDdkMsNkJBQUNLLDJCQUNDLDZCQUFDQTtRQUFJQyxXQUFXLENBQUMsRUFBRU4sVUFBVSxXQUFXLENBQUM7cUJBQ3ZDLDZCQUFDK0YsWUFBSTdFLEVBQUUscUNBQ1AsNkJBQUNxRCxlQUFNO1FBQ0xFLGFBQVk7UUFDWm5FLFdBQVcsQ0FBQyxFQUFFTixVQUFVLE9BQU8sQ0FBQztRQUNoQzBFLFNBQVNmO09BRVJ6QyxFQUFFLG1DQUlULDZCQUFDOEU7UUFBSzFGLFdBQVcsQ0FBQyxFQUFFTixVQUFVLGFBQWEsQ0FBQztPQUN6Q2tCLEVBQUUsZ0RBRUwsNkJBQUNiO1FBQUlDLFdBQVcsQ0FBQyxFQUFFTixVQUFVLFlBQVksQ0FBQztxQkFDeEMsNkJBQUNDO1FBQ0NDLE1BQUs7UUFDTEMsVUFBVSxDQUFDQyxRQUFVOEMsbUJBQW1CO2dCQUFFQyxZQUFZO2dCQUFLL0M7WUFBTTtRQUNqRUEsT0FBTzRCLGNBQWNGLENBQUMsQ0FBQ21FLE9BQU8sQ0FBQztzQkFFakMsNkJBQUNoRztRQUNDQyxNQUFLO1FBQ0xDLFVBQVUsQ0FBQ0MsUUFBVThDLG1CQUFtQjtnQkFBRUMsWUFBWTtnQkFBSy9DO1lBQU07UUFDakVBLE9BQU80QixjQUFjRCxDQUFDLENBQUNrRSxPQUFPLENBQUM7O0FBVW5EO0FBRUEsTUFBTVAsbUJBQW1CLENBQUMsRUFDeEJDLFNBQVMsRUFDVHhELFdBQVcsRUFDWCtELFFBQVEsRUFDUjVGLFNBQVMsRUFDVHNGLFlBQVksRUFDWkMsa0JBQWtCO0lBQUUvRCxHQUFHO0lBQUlDLEdBQUc7QUFBRyxDQUFDLEVBQ2xDeUIsU0FBUyxFQUNUcEIsY0FBYyxFQUNmO0lBQ0MsTUFBTSxDQUFDK0QsVUFBVUMsWUFBWSxHQUFHMUUsSUFBQUEsZUFBUSxFQUFDO1FBQUVJLEdBQUcrRCxnQkFBZ0IvRCxDQUFDO1FBQUVDLEdBQUc4RCxnQkFBZ0I5RCxDQUFDO0lBQUM7SUFDdEYsTUFBTSxDQUFDc0UsWUFBWUMsY0FBYyxHQUFHNUUsSUFBQUEsZUFBUSxFQUFDO0lBQzdDLE1BQU02RSxVQUFVN0QsSUFBQUEsYUFBTTtJQUV0QixNQUFNOEQsaUJBQWlCL0MsY0FBSyxDQUFDQyxXQUFXLENBQ3RDLENBQUMrQyxXQUFvQkMsV0FBb0JDO1FBQ3ZDLE1BQU0vQyxnQkFBZ0JnQyxhQUFhL0IsT0FBTyxDQUFDQyxxQkFBcUI7UUFDaEUsTUFBTUMsYUFBYTRCLFVBQVU5QixPQUFPLENBQUNDLHFCQUFxQjtRQUMxRCxNQUFNOEMsU0FBU0gsYUFBYTFDLFdBQVdFLElBQUk7UUFDM0MsTUFBTTRDLFNBQVNILGFBQWEzQyxXQUFXSSxHQUFHO1FBRTFDLE1BQU0yQyxlQUFlRixTQUFTN0MsV0FBV0UsSUFBSSxJQUFJMkMsU0FBUzdDLFdBQVdnRCxLQUFLO1FBQzFFLE1BQU1DLGVBQWVILFNBQVM5QyxXQUFXSSxHQUFHLElBQUkwQyxTQUFTOUMsV0FBV2tELE1BQU07UUFFMUUsSUFBSW5GLElBQUksQUFBRThFLENBQUFBLFNBQVNoRCxjQUFjSyxJQUFJLEFBQUQsSUFBS0wsY0FBYy9CLEtBQUssR0FBSTtRQUNoRSxJQUFJRSxJQUFJLEFBQUU4RSxDQUFBQSxTQUFTakQsY0FBY08sR0FBRyxBQUFELElBQUtQLGNBQWNqQyxNQUFNLEdBQUk7UUFDaEUsTUFBTXFDLFVBQ0osQUFBRUQsQ0FBQUEsV0FBV0UsSUFBSSxHQUFHTCxjQUFjSyxJQUFJLEdBQUdGLFdBQVdsQyxLQUFLLEdBQUcsQ0FBQSxJQUFLK0IsY0FBYy9CLEtBQUssR0FBSTtRQUMxRixNQUFNcUMsVUFDSixBQUFFSCxDQUFBQSxXQUFXSSxHQUFHLEdBQUdQLGNBQWNPLEdBQUcsR0FBR0osV0FBV3BDLE1BQU0sR0FBRyxDQUFBLElBQUtpQyxjQUFjakMsTUFBTSxHQUFJO1FBQzFGLElBQUltRixnQkFBZ0JFLGNBQWM7WUFDaENWLGNBQWM7WUFDZCxJQUFJTSxTQUFTN0MsV0FBV0UsSUFBSSxFQUFFO2dCQUM1Qm5DLElBQUksQUFBRWlDLENBQUFBLFdBQVdFLElBQUksR0FBR0wsY0FBY0ssSUFBSSxBQUFELElBQUtMLGNBQWMvQixLQUFLLEdBQUk7WUFDdkUsT0FBTyxJQUFJK0UsU0FBUzdDLFdBQVdnRCxLQUFLLEVBQUU7Z0JBQ3BDakYsSUFDRSxBQUFFOEIsQ0FBQUEsY0FBYy9CLEtBQUssR0FBSStCLENBQUFBLGNBQWNtRCxLQUFLLEdBQUdoRCxXQUFXZ0QsS0FBSyxBQUFELENBQUMsSUFDN0RuRCxjQUFjL0IsS0FBSyxHQUNyQjtZQUNKO1lBRUEsSUFBSWdGLFNBQVM5QyxXQUFXSSxHQUFHLEVBQUU7Z0JBQzNCcEMsSUFBSSxBQUFFZ0MsQ0FBQUEsV0FBV0ksR0FBRyxHQUFHUCxjQUFjTyxHQUFHLEFBQUQsSUFBS1AsY0FBY2pDLE1BQU0sR0FBSTtZQUN0RSxPQUFPLElBQUlrRixTQUFTOUMsV0FBV2tELE1BQU0sRUFBRTtnQkFDckNsRixJQUNFLEFBQUU2QixDQUFBQSxjQUFjakMsTUFBTSxHQUFJaUMsQ0FBQUEsY0FBY3FELE1BQU0sR0FBR2xELFdBQVdrRCxNQUFNLEFBQUQsQ0FBQyxJQUNoRXJELGNBQWNqQyxNQUFNLEdBQ3RCO1lBQ0o7WUFFQSxJQUFJZ0YsVUFBVTtnQkFDWjdFLElBQUlnRixlQUFlOUMsVUFBVWxDO2dCQUM3QkMsSUFBSWlGLGVBQWU5QyxVQUFVbkM7WUFDL0I7UUFDRjtRQUVBLE9BQU87WUFBRUQ7WUFBR0M7UUFBRTtJQUNoQixHQUNBO1FBQUM0RDtRQUFXQztLQUFhO0lBRzNCLE1BQU1zQixrQkFBa0IsQ0FBQ0M7UUFDdkJBLE1BQU1DLGNBQWM7UUFDcEJkLGNBQWM7SUFDaEI7SUFFQSxNQUFNZSxrQkFBa0IsQ0FBQ0Y7UUFDdkIsSUFBSSxDQUFDZCxZQUFZLE9BQU87UUFDeEIsTUFBTSxFQUFFdkUsQ0FBQyxFQUFFQyxDQUFDLEVBQUUsR0FBR3lFLGVBQWVXLE1BQU1HLE9BQU8sRUFBRUgsTUFBTUksT0FBTztRQUU1RG5CLFlBQVk7WUFBRXRFO1lBQUdDO1FBQUU7SUFDckI7SUFFQSxNQUFNeUYsU0FBUztRQUNibEIsY0FBYztRQUNkOUMsVUFBVTJDO0lBQ1o7SUFFQTFDLGNBQUssQ0FBQ2dFLFNBQVMsQ0FBQztRQUNkLElBQUlwQixjQUFjLENBQUNFLFFBQVExQyxPQUFPLEVBQUU7UUFDcEMsSUFBSTFCLGFBQWE7WUFDZixNQUFNLEVBQUVSLE1BQU0sRUFBRXNDLElBQUksRUFBRUUsR0FBRyxFQUFFdEMsS0FBSyxFQUFFLEdBQUcwRSxRQUFRMUMsT0FBTyxDQUFDQyxxQkFBcUI7WUFDMUUsTUFBTSxFQUFFaEMsQ0FBQyxFQUFFQyxDQUFDLEVBQUUsR0FBR3lFLGVBQWV2QyxPQUFPcEMsUUFBUSxHQUFHc0MsTUFBTXhDLFNBQVMsR0FBRztZQUNwRTZCLFVBQVU7Z0JBQUUxQjtnQkFBR0M7WUFBRTtZQUNqQnFFLFlBQVk7Z0JBQUV0RTtnQkFBR0M7WUFBRTtZQUNuQkssZUFBZTtZQUNmO1FBQ0Y7SUFDRixHQUFHO1FBQUNvRTtRQUFnQkg7UUFBWWxFO1FBQWFDO1FBQWdCK0QsU0FBU3JFLENBQUM7UUFBRXFFLFNBQVNwRSxDQUFDO1FBQUV5QjtLQUFVO0lBRS9GQyxjQUFLLENBQUNnRSxTQUFTLENBQUM7UUFDZHJCLFlBQVk7WUFBRXRFLEdBQUcrRCxnQkFBZ0IvRCxDQUFDO1lBQUVDLEdBQUc4RCxnQkFBZ0I5RCxDQUFDO1FBQUM7SUFDM0QsR0FBRztRQUFDOEQsZ0JBQWdCL0QsQ0FBQztRQUFFK0QsZ0JBQWdCOUQsQ0FBQztLQUFDO0lBRXpDLHFCQUNFLDZCQUFDMUI7UUFDQ0MsV0FBVztZQUNULENBQUMsRUFBRU4sVUFBVSxxQkFBcUIsQ0FBQztZQUNuQ3FHLGNBQWMsQ0FBQyxFQUFFckcsVUFBVSwrQkFBK0IsQ0FBQztTQUM1RCxDQUNFMEgsTUFBTSxDQUFDQyxTQUNQQyxJQUFJLENBQUM7UUFDUkMsYUFBYVI7cUJBRWIsNkJBQUNTO1FBQ0N4SCxXQUFXO1lBQUMsQ0FBQyxFQUFFTixVQUFVLFdBQVcsQ0FBQztZQUFFTTtTQUFVLENBQUNvSCxNQUFNLENBQUNDLFNBQVNDLElBQUksQ0FBQztRQUN2RUcsYUFBYWI7UUFDYmMsV0FBV1I7UUFDWDdDLEtBQUs0QjtRQUNMM0IsT0FBTztZQUFFWCxNQUFNLENBQUMsRUFBRWtDLFNBQVNyRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQUVxQyxLQUFLLENBQUMsRUFBRWdDLFNBQVNwRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQUM7UUFDdkRyQixNQUFLO09BRUp3Rix5QkFFSCw2QkFBQzdGO0FBR1AifQ==