@alauda-fe/common
Version:
Alauda frontend team common codes.
247 lines • 42.6 kB
JavaScript
import { clamp } from 'lodash-es';
import { GridCompactType, } from '../type';
import { getPointerPageX, getPointerPageY } from './mouse.utils';
import { compact, getFirstCollision, moveElement, } from './react-grid-layout.utils';
function clampSize(size, min = 1, max = Infinity) {
return clamp(size, min || 1, max || Infinity);
}
export function trackById(_index, item) {
return item.id;
}
/**
* call react-grid-layout utils 'compact()' function and return the compacted layout.
*/
export function compactGridLayout(layout, compactType, cols) {
return (compact(layout, compactType, cols)
// Prune react-grid-layout compact extra properties.
.map(item => ({
id: item.id,
x: item.x,
y: item.y,
w: item.w,
h: item.h,
minW: item.minW,
minH: item.minH,
maxW: item.maxW,
maxH: item.maxH,
})));
}
// convert web page absolute position to grid layout location (used for locate last position)
function screenXToGridX(screenXPos, cols, width, gutter) {
const widthMinusGutters = width - gutter * (cols - 1);
const itemWidth = widthMinusGutters / cols;
const widthMinusOneItem = width - itemWidth;
const colWidthWithGutter = widthMinusOneItem / (cols - 1);
return Math.round(screenXPos / colWidthWithGutter);
}
function screenYToGridY(screenYPos, rowHeight, gutter) {
return Math.round(screenYPos / (rowHeight + gutter));
}
// convert web page absolute size to grid layout size (used for locate last position)
function screenWidthToGridWidth(gridScreenWidth, cols, width, gutter) {
const widthMinusGutters = width - gutter * (cols - 1);
const itemWidth = widthMinusGutters / cols;
const gridScreenWidthMinusFirst = gridScreenWidth - itemWidth;
return Math.round(gridScreenWidthMinusFirst / (itemWidth + gutter)) + 1;
}
function screenHeightToGridHeight(gridScreenHeight, rowHeight, gutter) {
const gridScreenHeightMinusFirst = gridScreenHeight - rowHeight;
return Math.round(gridScreenHeightMinusFirst / (rowHeight + gutter)) + 1;
}
/** Returns a Dictionary where the key is the id and the value is the change applied to that item. If no changes Dictionary is empty. */
export function getGetGridLayoutDiff(gridLayoutA, gridLayoutB) {
const diff = {};
gridLayoutA.forEach(itemA => {
const itemB = gridLayoutB.find(_itemB => _itemB.id === itemA.id);
if (itemB != null) {
const posChanged = itemA.x !== itemB.x || itemA.y !== itemB.y;
const sizeChanged = itemA.w !== itemB.w || itemA.h !== itemB.h;
const change = posChanged && sizeChanged
? 'moveresize'
: posChanged
? 'move'
: sizeChanged
? 'resize'
: null;
if (change) {
diff[itemB.id] = { change };
}
}
});
return diff;
}
// get the on-flight dragging item position and its last position(used for placeholder)
export function gridItemDragging(gridItem, config, compactType, draggingData) {
const { pointerDownEvent, pointerDragEvent, gridElemClientRect, dragElemClientRect, scrollDifference, } = draggingData;
const gridItemId = gridItem.id;
const draggingElemPrevItem = config.layout.find(item => item.id === gridItemId);
const clientStartX = getPointerPageX(pointerDownEvent);
const clientStartY = getPointerPageY(pointerDownEvent);
const clientX = getPointerPageX(pointerDragEvent);
const clientY = getPointerPageY(pointerDragEvent);
const offsetX = clientStartX - dragElemClientRect.left;
const offsetY = clientStartY - dragElemClientRect.top;
// Grid element positions taking into account the possible scroll total difference from the beginning.
const gridElementLeftPosition = gridElemClientRect.left + scrollDifference.left;
const gridElementTopPosition = gridElemClientRect.top + scrollDifference.top;
// Calculate position relative to the grid element.
const gridRelXPos = clientX - gridElementLeftPosition - offsetX;
const gridRelYPos = clientY - gridElementTopPosition - offsetY;
// Get layout item position
const layoutItem = {
...draggingElemPrevItem,
x: screenXToGridX(gridRelXPos, config.cols, gridElemClientRect.width, config.gutter),
y: screenYToGridY(gridRelYPos, config.rowHeight, config.gutter),
};
// correct the values if they overflow
layoutItem.x = Math.max(0, layoutItem.x);
layoutItem.y = Math.max(0, layoutItem.y);
if (layoutItem.x + layoutItem.w > config.cols) {
layoutItem.x = Math.max(0, config.cols - layoutItem.w);
}
// Parse to LayoutItem array data in order to use 'react.grid-layout' utils
const layoutItems = config.layout;
const draggedLayoutItem = layoutItems.find(item => item.id === gridItemId);
let newLayoutItems = moveElement(layoutItems, draggedLayoutItem, layoutItem.x, layoutItem.y, true, config.preventCollision, compactType, config.cols);
newLayoutItems = compact(newLayoutItems, compactType, config.cols);
const dragItem = {
...draggingElemPrevItem,
// items layout boundary will changed by compactType, when vertical,we can let bottom grow. when horizontal,we let right and bottom grow.
// so, left and top will always bound to 0.
top: clampSize(gridRelYPos, 0, Infinity),
left: clampSize(gridRelXPos, 0, compactType === GridCompactType.VERTICAL
? gridElemClientRect.width - dragElemClientRect.width
: Infinity),
};
return {
layout: newLayoutItems,
draggedItemPos: dragItem,
};
}
// eslint-disable-next-line sonarjs/cognitive-complexity
export function gridItemResizing(gridItem, config, compactType, draggingData) {
const { pointerDownEvent, pointerDragEvent, gridElemClientRect, dragElemClientRect, scrollDifference, } = draggingData;
const gridItemId = gridItem.id;
// use page offset to avoid scrolling offset caused by page shrink
const clientStartX = getPointerPageX(pointerDownEvent);
const clientStartY = getPointerPageY(pointerDownEvent);
const clientX = getPointerPageX(pointerDragEvent);
const clientY = getPointerPageY(pointerDragEvent);
// get the difference between the mouseDown and on-flight mouseDragging.
const resizeElemOffsetX = clientX - clientStartX;
const resizeElemOffsetY = clientY - clientStartY;
const draggingElemPrevItem = config.layout.find(item => item.id === gridItemId);
const width = dragElemClientRect.width + resizeElemOffsetX - scrollDifference.left;
const height = dragElemClientRect.height + resizeElemOffsetY - scrollDifference.top;
// Get layout item grid position
const layoutItem = {
...draggingElemPrevItem,
w: screenWidthToGridWidth(width, config.cols, gridElemClientRect.width, config.gutter),
h: screenHeightToGridHeight(height, config.rowHeight, config.gutter),
};
layoutItem.w = clampSize(layoutItem.w, gridItem.minW ?? layoutItem.minW, gridItem.maxW ?? layoutItem.maxW);
layoutItem.h = clampSize(layoutItem.h, gridItem.minH ?? layoutItem.minH, gridItem.maxH ?? layoutItem.maxH);
if (layoutItem.x + layoutItem.w > config.cols) {
layoutItem.w = Math.max(1, config.cols - layoutItem.x);
}
if (config.preventCollision) {
const maxW = layoutItem.w;
const maxH = layoutItem.h;
let colliding = hasCollision(config.layout, layoutItem);
let shrunkDimension;
while (colliding) {
shrunkDimension = getShrinkDimension(layoutItem, shrunkDimension);
layoutItem[shrunkDimension]--;
colliding = hasCollision(config.layout, layoutItem);
}
if (shrunkDimension === 'w') {
layoutItem.h = maxH;
colliding = hasCollision(config.layout, layoutItem);
while (colliding) {
layoutItem.h--;
colliding = hasCollision(config.layout, layoutItem);
}
}
if (shrunkDimension === 'h') {
layoutItem.w = maxW;
colliding = hasCollision(config.layout, layoutItem);
while (colliding) {
layoutItem.w--;
colliding = hasCollision(config.layout, layoutItem);
}
}
}
const newLayoutItems = config.layout.map(item => item.id === gridItemId ? layoutItem : item);
return {
layout: compact(newLayoutItems, compactType, config.cols),
draggedItemPos: {
top: dragElemClientRect.top - gridElemClientRect.top,
left: dragElemClientRect.left - gridElemClientRect.left,
// when vertical, make sure resizing not overflow right boundary
width: clampSize(width, 0, compactType === GridCompactType.VERTICAL
? (gridElemClientRect.width * (config.cols - layoutItem.x)) /
config.cols
: Infinity),
height,
},
};
}
function hasCollision(layout, layoutItem) {
return !!getFirstCollision(layout, layoutItem);
}
function getShrinkDimension(layoutItem, lastShrunk) {
if (layoutItem.h <= 1) {
return 'w';
}
if (layoutItem.w <= 1) {
return 'h';
}
return lastShrunk === 'w' ? 'h' : 'w';
}
/** Returns true if both item1 and item2 GridLayoutItems are equivalent. */
export function isGridItemLayoutItemEqual(item1, item2) {
return (item1.id === item2.id &&
item1.x === item2.x &&
item1.y === item2.y &&
item1.w === item2.w &&
item1.h === item2.h);
}
export function getGridHeight(layout, rowHeight, gutter) {
return layout.reduce((acc, cur) => Math.max(acc, (cur.y + cur.h) * rowHeight + Math.max(cur.y + cur.h - 1, 0) * gutter), 0);
}
export function getDragResizeEventData(gridItem, layout) {
return {
layout,
layoutItem: layout.find(item => item.id === gridItem.id),
gridItemRef: gridItem,
};
}
export function layoutToRenderItems(config, width, layout) {
const { cols, rowHeight, layout: rawLayout, gutter } = config;
const widthWithoutGutter = width - Math.max(gutter * (cols - 1), 0);
const itemWidthPerColumn = widthWithoutGutter / cols;
const renderItems = {};
for (const item of layout ?? rawLayout) {
renderItems[item.id] = {
id: item.id,
top: item.y * rowHeight + gutter * item.y,
left: item.x * itemWidthPerColumn + gutter * item.x,
width: item.w * itemWidthPerColumn + gutter * Math.max(item.w - 1, 0),
height: item.h * rowHeight + gutter * Math.max(item.h - 1, 0),
};
}
return renderItems;
}
export function parseRenderItemToPixels(renderItem) {
return {
id: renderItem.id,
top: `${renderItem.top}px`,
left: `${renderItem.left}px`,
width: `${renderItem.width}px`,
height: `${renderItem.height}px`,
};
}
export function correctLayout(layout, cols = 12) {
return compactGridLayout(layout, 'vertical', cols);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JpZC51dGlscy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvY29tbW9uL3NyYy9ncmlkLWxheW91dC91dGlscy9ncmlkLnV0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFJbEMsT0FBTyxFQUdMLGVBQWUsR0FPaEIsTUFBTSxTQUFTLENBQUM7QUFFakIsT0FBTyxFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDakUsT0FBTyxFQUNMLE9BQU8sRUFFUCxpQkFBaUIsRUFHakIsV0FBVyxHQUNaLE1BQU0sMkJBQTJCLENBQUM7QUFFbkMsU0FBUyxTQUFTLENBQUMsSUFBWSxFQUFFLEdBQUcsR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLFFBQVE7SUFDdEQsT0FBTyxLQUFLLENBQUMsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLFFBQVEsQ0FBQyxDQUFDO0FBQ2hELENBQUM7QUFFRCxNQUFNLFVBQVUsU0FBUyxDQUFDLE1BQWMsRUFBRSxJQUFvQjtJQUM1RCxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUM7QUFDakIsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUMvQixNQUFrQixFQUNsQixXQUE0QixFQUM1QixJQUFZO0lBRVosT0FBTyxDQUNMLE9BQU8sQ0FBQyxNQUFNLEVBQUUsV0FBVyxFQUFFLElBQUksQ0FBQztRQUNoQyxvREFBb0Q7U0FDbkQsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNaLEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBRTtRQUNYLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNULENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNULENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNULENBQUMsRUFB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QUFHLElBQUksQ0FBQyxDQUFDO1lBQ3pDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxHQUFHLGtCQUFrQixHQUFHLE1BQU0sR0FBRyxJQUFJLENBQUMsQ0FBQztZQUNuRCxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUMsR0FBRyxrQkFBa0IsR0FBRyxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDckUsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDLEdBQUcsU0FBUyxHQUFHLE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztTQUM5RCxDQUFDO0lBQ0osQ0FBQztJQUNELE9BQU8sV0FBVyxDQUFDO0FBQ3JCLENBQUM7QUFFRCxNQUFNLFVBQVUsdUJBQXVCLENBQ3JDLFVBQThCO0lBRTlCLE9BQU87UUFDTCxFQUFFLEVBQUUsVUFBVSxDQUFDLEVBQUU7UUFDakIsR0FBRyxFQUFFLEdBQUcsVUFBVSxDQUFDLEdBQUcsSUFBSTtRQUMxQixJQUFJLEVBQUUsR0FBRyxVQUFVLENBQUMsSUFBSSxJQUFJO1FBQzVCLEtBQUssRUFBRSxHQUFHLFVBQVUsQ0FBQyxLQUFLLElBQUk7UUFDOUIsTUFBTSxFQUFFLEdBQUcsVUFBVSxDQUFDLE1BQU0sSUFBSTtLQUNqQyxDQUFDO0FBQ0osQ0FBQztBQUVELE1BQU0sVUFBVSxhQUFhLENBQUMsTUFBa0IsRUFBRSxJQUFJLEdBQUcsRUFBRTtJQUN6RCxPQUFPLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDckQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNsYW1wIH0gZnJvbSAnbG9kYXNoLWVzJztcblxuaW1wb3J0IHsgRGljdGlvbmFyeSB9IGZyb20gJy4uLy4uL3B1YmxpYy1hcGknO1xuaW1wb3J0IHsgR3JpZEl0ZW1Db21wb25lbnQgfSBmcm9tICcuLi9jb21wb25lbnRzL2dyaWQtaXRlbXMvY29tcG9uZW50JztcbmltcG9ydCB7XG4gIERyYWdSZXNpemVFdmVudCxcbiAgR3JpZENmZyxcbiAgR3JpZENvbXBhY3RUeXBlLFxuICBHcmlkSXRlbUNsaWVudFJlY3QsXG4gIEdyaWRJdGVtRGltZW5zaW9uLFxuICBHcmlkSXRlbURyYWdnaW5nSW5mbyxcbiAgR3JpZEl0ZW1SZW5kZXJEYXRhLFxuICBHcmlkTGF5b3V0LFxuICBHcmlkTGF5b3V0SXRlbSxcbn0gZnJvbSAnLi4vdHlwZSc7XG5cbmltcG9ydCB7IGdldFBvaW50ZXJQYWdlWCwgZ2V0UG9pbnRlclBhZ2VZIH0gZnJvbSAnLi9tb3VzZS51dGlscyc7XG5pbXBvcnQge1xuICBjb21wYWN0LFxuICBDb21wYWN0VHlwZSxcbiAgZ2V0Rmlyc3RDb2xsaXNpb24sXG4gIExheW91dCxcbiAgTGF5b3V0SXRlbSxcbiAgbW92ZUVsZW1lbnQsXG59IGZyb20gJy4vcmVhY3QtZ3JpZC1sYXlvdXQudXRpbHMnO1xuXG5mdW5jdGlvbiBjbGFtcFNpemUoc2l6ZTogbnVtYmVyLCBtaW4gPSAxLCBtYXggPSBJbmZpbml0eSkge1xuICByZXR1cm4gY2xhbXAoc2l6ZSwgbWluIHx8IDEsIG1heCB8fCBJbmZpbml0eSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0cmFja0J5SWQoX2luZGV4OiBudW1iZXIsIGl0ZW06IHsgaWQ6IHN0cmluZyB9KSB7XG4gIHJldHVybiBpdGVtLmlkO1xufVxuXG4vKipcbiAqIGNhbGwgcmVhY3QtZ3JpZC1sYXlvdXQgdXRpbHMgJ2NvbXBhY3QoKScgZnVuY3Rpb24gYW5kIHJldHVybiB0aGUgY29tcGFjdGVkIGxheW91dC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbXBhY3RHcmlkTGF5b3V0KFxuICBsYXlvdXQ6IEdyaWRMYXlvdXQsXG4gIGNvbXBhY3RUeXBlOiBHcmlkQ29tcGFjdFR5cGUsXG4gIGNvbHM6IG51bWJlcixcbik6IEdyaWRMYXlvdXQge1xuICByZXR1cm4gKFxuICAgIGNvbXBhY3QobGF5b3V0LCBjb21wYWN0VHlwZSwgY29scylcbiAgICAgIC8vIFBydW5lIHJlYWN0LWdyaWQtbGF5b3V0IGNvbXBhY3QgZXh0cmEgcHJvcGVydGllcy5cbiAgICAgIC5tYXAoaXRlbSA9PiAoe1xuICAgICAgICBpZDogaXRlbS5pZCxcbiAgICAgICAgeDogaXRlbS54LFxuICAgICAgICB5OiBpdGVtLnksXG4gICAgICAgIHc6IGl0ZW0udyxcbiAgICAgICAgaDogaXRlbS5oLFxuICAgICAgICBtaW5XOiBpdGVtLm1pblcsXG4gICAgICAgIG1pbkg6IGl0ZW0ubWluSCxcbiAgICAgICAgbWF4VzogaXRlbS5tYXhXLFxuICAgICAgICBtYXhIOiBpdGVtLm1heEgsXG4gICAgICB9KSlcbiAgKTtcbn1cblxuLy8gY29udmVydCB3ZWIgcGFnZSBhYnNvbHV0ZSBwb3NpdGlvbiB0byBncmlkIGxheW91dCBsb2NhdGlvbiAodXNlZCBmb3IgbG9jYXRlIGxhc3QgcG9zaXRpb24pXG5mdW5jdGlvbiBzY3JlZW5YVG9HcmlkWChcbiAgc2NyZWVuWFBvczogbnVtYmVyLFxuICBjb2xzOiBudW1iZXIsXG4gIHdpZHRoOiBudW1iZXIsXG4gIGd1dHRlcjogbnVtYmVyLFxuKTogbnVtYmVyIHtcbiAgY29uc3Qgd2lkdGhNaW51c0d1dHRlcnMgPSB3aWR0aCAtIGd1dHRlciAqIChjb2xzIC0gMSk7XG4gIGNvbnN0IGl0ZW1XaWR0aCA9IHdpZHRoTWludXNHdXR0ZXJzIC8gY29scztcbiAgY29uc3Qgd2lkdGhNaW51c09uZUl0ZW0gPSB3aWR0aCAtIGl0ZW1XaWR0aDtcbiAgY29uc3QgY29sV2lkdGhXaXRoR3V0dGVyID0gd2lkdGhNaW51c09uZUl0ZW0gLyAoY29scyAtIDEpO1xuICByZXR1cm4gTWF0aC5yb3VuZChzY3JlZW5YUG9zIC8gY29sV2lkdGhXaXRoR3V0dGVyKTtcbn1cblxuZnVuY3Rpb24gc2NyZWVuWVRvR3JpZFkoXG4gIHNjcmVlbllQb3M6IG51bWJlcixcbiAgcm93SGVpZ2h0OiBudW1iZXIsXG4gIGd1dHRlcjogbnVtYmVyLFxuKTogbnVtYmVyIHtcbiAgcmV0dXJuIE1hdGgucm91bmQoc2NyZWVuWVBvcyAvIChyb3dIZWlnaHQgKyBndXR0ZXIpKTtcbn1cbi8vIGNvbnZlcnQgd2ViIHBhZ2UgYWJzb2x1dGUgc2l6ZSB0byBncmlkIGxheW91dCBzaXplICh1c2VkIGZvciBsb2NhdGUgbGFzdCBwb3NpdGlvbilcbmZ1bmN0aW9uIHNjcmVlbldpZHRoVG9HcmlkV2lkdGgoXG4gIGdyaWRTY3JlZW5XaWR0aDogbnVtYmVyLFxuICBjb2xzOiBudW1iZXIsXG4gIHdpZHRoOiBudW1iZXIsXG4gIGd1dHRlcjogbnVtYmVyLFxuKTogbnVtYmVyIHtcbiAgY29uc3Qgd2lkdGhNaW51c0d1dHRlcnMgPSB3aWR0aCAtIGd1dHRlciAqIChjb2xzIC0gMSk7XG4gIGNvbnN0IGl0ZW1XaWR0aCA9IHdpZHRoTWludXNHdXR0ZXJzIC8gY29scztcbiAgY29uc3QgZ3JpZFNjcmVlbldpZHRoTWludXNGaXJzdCA9IGdyaWRTY3JlZW5XaWR0aCAtIGl0ZW1XaWR0aDtcbiAgcmV0dXJuIE1hdGgucm91bmQoZ3JpZFNjcmVlbldpZHRoTWludXNGaXJzdCAvIChpdGVtV2lkdGggKyBndXR0ZXIpKSArIDE7XG59XG5cbmZ1bmN0aW9uIHNjcmVlbkhlaWdodFRvR3JpZEhlaWdodChcbiAgZ3JpZFNjcmVlbkhlaWdodDogbnVtYmVyLFxuICByb3dIZWlnaHQ6IG51bWJlcixcbiAgZ3V0dGVyOiBudW1iZXIsXG4pOiBudW1iZXIge1xuICBjb25zdCBncmlkU2NyZWVuSGVpZ2h0TWludXNGaXJzdCA9IGdyaWRTY3JlZW5IZWlnaHQgLSByb3dIZWlnaHQ7XG4gIHJldHVybiBNYXRoLnJvdW5kKGdyaWRTY3JlZW5IZWlnaHRNaW51c0ZpcnN0IC8gKHJvd0hlaWdodCArIGd1dHRlcikpICsgMTtcbn1cblxuLyoqIFJldHVybnMgYSBEaWN0aW9uYXJ5IHdoZXJlIHRoZSBrZXkgaXMgdGhlIGlkIGFuZCB0aGUgdmFsdWUgaXMgdGhlIGNoYW5nZSBhcHBsaWVkIHRvIHRoYXQgaXRlbS4gSWYgbm8gY2hhbmdlcyBEaWN0aW9uYXJ5IGlzIGVtcHR5LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEdldEdyaWRMYXlvdXREaWZmKFxuICBncmlkTGF5b3V0QTogR3JpZExheW91dEl0ZW1bXSxcbiAgZ3JpZExheW91dEI6IEdyaWRMYXlvdXRJdGVtW10sXG4pOiBEaWN0aW9uYXJ5PHsgY2hhbmdlOiAnbW92ZScgfCAncmVzaXplJyB8ICdtb3ZlcmVzaXplJyB9PiB7XG4gIGNvbnN0IGRpZmY6IERpY3Rpb25hcnk8eyBjaGFuZ2U6ICdtb3ZlJyB8ICdyZXNpemUnIHwgJ21vdmVyZXNpemUnIH0+ID0ge307XG5cbiAgZ3JpZExheW91dEEuZm9yRWFjaChpdGVtQSA9PiB7XG4gICAgY29uc3QgaXRlbUIgPSBncmlkTGF5b3V0Qi5maW5kKF9pdGVtQiA9PiBfaXRlbUIuaWQgPT09IGl0ZW1BLmlkKTtcbiAgICBpZiAoaXRlbUIgIT0gbnVsbCkge1xuICAgICAgY29uc3QgcG9zQ2hhbmdlZCA9IGl0ZW1BLnggIT09IGl0ZW1CLnggfHwgaXRlbUEueSAhPT0gaXRlbUIueTtcbiAgICAgIGNvbnN0IHNpemVDaGFuZ2VkID0gaXRlbUEudyAhPT0gaXRlbUIudyB8fCBpdGVtQS5oICE9PSBpdGVtQi5oO1xuICAgICAgY29uc3QgY2hhbmdlOiAnbW92ZScgfCAncmVzaXplJyB8ICdtb3ZlcmVzaXplJyB8IG51bGwgPVxuICAgICAgICBwb3NDaGFuZ2VkICYmIHNpemVDaGFuZ2VkXG4gICAgICAgICAgPyAnbW92ZXJlc2l6ZSdcbiAgICAgICAgICA6IHBvc0NoYW5nZWRcbiAgICAgICAgICA/ICdtb3ZlJ1xuICAgICAgICAgIDogc2l6ZUNoYW5nZWRcbiAgICAgICAgICA/ICdyZXNpemUnXG4gICAgICAgICAgOiBudWxsO1xuICAgICAgaWYgKGNoYW5nZSkge1xuICAgICAgICBkaWZmW2l0ZW1CLmlkXSA9IHsgY2hhbmdlIH07XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIGRpZmY7XG59XG5cbi8vIGdldCB0aGUgb24tZmxpZ2h0IGRyYWdnaW5nIGl0ZW0gcG9zaXRpb24gYW5kIGl0cyBsYXN0IHBvc2l0aW9uKHVzZWQgZm9yIHBsYWNlaG9sZGVyKVxuZXhwb3J0IGZ1bmN0aW9uIGdyaWRJdGVtRHJhZ2dpbmcoXG4gIGdyaWRJdGVtOiBHcmlkSXRlbUNvbXBvbmVudCxcbiAgY29uZmlnOiBHcmlkQ2ZnLFxuICBjb21wYWN0VHlwZTogQ29tcGFjdFR5cGUsXG4gIGRyYWdnaW5nRGF0YTogR3JpZEl0ZW1EcmFnZ2luZ0luZm8sXG4pOiB7IGxheW91dDogR3JpZExheW91dEl0ZW1bXTsgZHJhZ2dlZEl0ZW1Qb3M6IEdyaWRJdGVtQ2xpZW50UmVjdCB9IHtcbiAgY29uc3Qge1xuICAgIHBvaW50ZXJEb3duRXZlbnQsXG4gICAgcG9pbnRlckRyYWdFdmVudCxcbiAgICBncmlkRWxlbUNsaWVudFJlY3QsXG4gICAgZHJhZ0VsZW1DbGllbnRSZWN0LFxuICAgIHNjcm9sbERpZmZlcmVuY2UsXG4gIH0gPSBkcmFnZ2luZ0RhdGE7XG5cbiAgY29uc3QgZ3JpZEl0ZW1JZCA9IGdyaWRJdGVtLmlkO1xuICBjb25zdCBkcmFnZ2luZ0VsZW1QcmV2SXRlbSA9IGNvbmZpZy5sYXlvdXQuZmluZChcbiAgICBpdGVtID0+IGl0ZW0uaWQgPT09IGdyaWRJdGVtSWQsXG4gICkhO1xuXG4gIGNvbnN0IGNsaWVudFN0YXJ0WCA9IGdldFBvaW50ZXJQYWdlWChwb2ludGVyRG93bkV2ZW50KTtcbiAgY29uc3QgY2xpZW50U3RhcnRZID0gZ2V0UG9pbnRlclBhZ2VZKHBvaW50ZXJEb3duRXZlbnQpO1xuICBjb25zdCBjbGllbnRYID0gZ2V0UG9pbnRlclBhZ2VYKHBvaW50ZXJEcmFnRXZlbnQpO1xuICBjb25zdCBjbGllbnRZID0gZ2V0UG9pbnRlclBhZ2VZKHBvaW50ZXJEcmFnRXZlbnQpO1xuXG4gIGNvbnN0IG9mZnNldFggPSBjbGllbnRTdGFydFggLSBkcmFnRWxlbUNsaWVudFJlY3QubGVmdDtcbiAgY29uc3Qgb2Zmc2V0WSA9IGNsaWVudFN0YXJ0WSAtIGRyYWdFbGVtQ2xpZW50UmVjdC50b3A7XG5cbiAgLy8gR3JpZCBlbGVtZW50IHBvc2l0aW9ucyB0YWtpbmcgaW50byBhY2NvdW50IHRoZSBwb3NzaWJsZSBzY3JvbGwgdG90YWwgZGlmZmVyZW5jZSBmcm9tIHRoZSBiZWdpbm5pbmcuXG4gIGNvbnN0IGdyaWRFbGVtZW50TGVmdFBvc2l0aW9uID1cbiAgICBncmlkRWxlbUNsaWVudFJlY3QubGVmdCArIHNjcm9sbERpZmZlcmVuY2UubGVmdDtcbiAgY29uc3QgZ3JpZEVsZW1lbnRUb3BQb3NpdGlvbiA9IGdyaWRFbGVtQ2xpZW50UmVjdC50b3AgKyBzY3JvbGxEaWZmZXJlbmNlLnRvcDtcbiAgLy8gQ2FsY3VsYXRlIHBvc2l0aW9uIHJlbGF0aXZlIHRvIHRoZSBncmlkIGVsZW1lbnQuXG4gIGNvbnN0IGdyaWRSZWxYUG9zID0gY2xpZW50WCAtIGdyaWRFbGVtZW50TGVmdFBvc2l0aW9uIC0gb2Zmc2V0WDtcblxuICBjb25zdCBncmlkUmVsWVBvcyA9IGNsaWVudFkgLSBncmlkRWxlbWVudFRvcFBvc2l0aW9uIC0gb2Zmc2V0WTtcblxuICAvLyBHZXQgbGF5b3V0IGl0ZW0gcG9zaXRpb25cbiAgY29uc3QgbGF5b3V0SXRlbTogR3JpZExheW91dEl0ZW0gPSB7XG4gICAgLi4uZHJhZ2dpbmdFbGVtUHJldkl0ZW0sXG4gICAgeDogc2NyZWVuWFRvR3JpZFgoXG4gICAgICBncmlkUmVsWFBvcyxcbiAgICAgIGNvbmZpZy5jb2xzLFxuICAgICAgZ3JpZEVsZW1DbGllbnRSZWN0LndpZHRoLFxuICAgICAgY29uZmlnLmd1dHRlcixcbiAgICApLFxuICAgIHk6IHNjcmVlbllUb0dyaWRZKGdyaWRSZWxZUG9zLCBjb25maWcucm93SGVpZ2h0LCBjb25maWcuZ3V0dGVyKSxcbiAgfTtcblxuICAvLyBjb3JyZWN0IHRoZSB2YWx1ZXMgaWYgdGhleSBvdmVyZmxvd1xuICBsYXlvdXRJdGVtLnggPSBNYXRoLm1heCgwLCBsYXlvdXRJdGVtLngpO1xuICBsYXlvdXRJdGVtLnkgPSBNYXRoLm1heCgwLCBsYXlvdXRJdGVtLnkpO1xuXG4gIGlmIChsYXlvdXRJdGVtLnggKyBsYXlvdXRJdGVtLncgPiBjb25maWcuY29scykge1xuICAgIGxheW91dEl0ZW0ueCA9IE1hdGgubWF4KDAsIGNvbmZpZy5jb2xzIC0gbGF5b3V0SXRlbS53KTtcbiAgfVxuXG4gIC8vIFBhcnNlIHRvIExheW91dEl0ZW0gYXJyYXkgZGF0YSBpbiBvcmRlciB0byB1c2UgJ3JlYWN0LmdyaWQtbGF5b3V0JyB1dGlsc1xuICBjb25zdCBsYXlvdXRJdGVtczogTGF5b3V0SXRlbVtdID0gY29uZmlnLmxheW91dDtcbiAgY29uc3QgZHJhZ2dlZExheW91dEl0ZW06IExheW91dEl0ZW0gPSBsYXlvdXRJdGVtcy5maW5kKFxuICAgIGl0ZW0gPT4gaXRlbS5pZCA9PT0gZ3JpZEl0ZW1JZCxcbiAgKSE7XG5cbiAgbGV0IG5ld0xheW91dEl0ZW1zOiBMYXlvdXRJdGVtW10gPSBtb3ZlRWxlbWVudChcbiAgICBsYXlvdXRJdGVtcyxcbiAgICBkcmFnZ2VkTGF5b3V0SXRlbSxcbiAgICBsYXlvdXRJdGVtLngsXG4gICAgbGF5b3V0SXRlbS55LFxuICAgIHRydWUsXG4gICAgY29uZmlnLnByZXZlbnRDb2xsaXNpb24sXG4gICAgY29tcGFjdFR5cGUsXG4gICAgY29uZmlnLmNvbHMsXG4gICk7XG5cbiAgbmV3TGF5b3V0SXRlbXMgPSBjb21wYWN0KG5ld0xheW91dEl0ZW1zLCBjb21wYWN0VHlwZSwgY29uZmlnLmNvbHMpO1xuICBjb25zdCBkcmFnSXRlbSA9IHtcbiAgICAuLi5kcmFnZ2luZ0VsZW1QcmV2SXRlbSxcbiAgICAvLyBpdGVtcyBsYXlvdXQgYm91bmRhcnkgd2lsbCBjaGFuZ2VkIGJ5IGNvbXBhY3RUeXBlLCB3aGVuIHZlcnRpY2FsLHdlIGNhbiBsZXQgYm90dG9tIGdyb3cuIHdoZW4gaG9yaXpvbnRhbCx3ZSBsZXQgcmlnaHQgYW5kIGJvdHRvbSBncm93LlxuICAgIC8vIHNvLCBsZWZ0IGFuZCB0b3Agd2lsbCBhbHdheXMgYm91bmQgdG8gMC5cbiAgICB0b3A6IGNsYW1wU2l6ZShncmlkUmVsWVBvcywgMCwgSW5maW5pdHkpLFxuICAgIGxlZnQ6IGNsYW1wU2l6ZShcbiAgICAgIGdyaWRSZWxYUG9zLFxuICAgICAgMCxcbiAgICAgIGNvbXBhY3RUeXBlID09PSBHcmlkQ29tcGFjdFR5cGUuVkVSVElDQUxcbiAgICAgICAgPyBncmlkRWxlbUNsaWVudFJlY3Qud2lkdGggLSBkcmFnRWxlbUNsaWVudFJlY3Qud2lkdGhcbiAgICAgICAgOiBJbmZpbml0eSxcbiAgICApLFxuICB9O1xuICByZXR1cm4ge1xuICAgIGxheW91dDogbmV3TGF5b3V0SXRlbXMsXG4gICAgZHJhZ2dlZEl0ZW1Qb3M6IGRyYWdJdGVtLFxuICB9O1xufVxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgc29uYXJqcy9jb2duaXRpdmUtY29tcGxleGl0eVxuZXhwb3J0IGZ1bmN0aW9uIGdyaWRJdGVtUmVzaXppbmcoXG4gIGdyaWRJdGVtOiBHcmlkSXRlbUNvbXBvbmVudCxcbiAgY29uZmlnOiBHcmlkQ2ZnLFxuICBjb21wYWN0VHlwZTogQ29tcGFjdFR5cGUsXG4gIGRyYWdnaW5nRGF0YTogR3JpZEl0ZW1EcmFnZ2luZ0luZm8sXG4pOiB7IGxheW91dDogR3JpZExheW91dEl0ZW1bXTsgZHJhZ2dlZEl0ZW1Qb3M6IEdyaWRJdGVtQ2xpZW50UmVjdCB9IHtcbiAgY29uc3Qge1xuICAgIHBvaW50ZXJEb3duRXZlbnQsXG4gICAgcG9pbnRlckRyYWdFdmVudCxcbiAgICBncmlkRWxlbUNsaWVudFJlY3QsXG4gICAgZHJhZ0VsZW1DbGllbnRSZWN0LFxuICAgIHNjcm9sbERpZmZlcmVuY2UsXG4gIH0gPSBkcmFnZ2luZ0RhdGE7XG4gIGNvbnN0IGdyaWRJdGVtSWQgPSBncmlkSXRlbS5pZDtcblxuICAvLyB1c2UgcGFnZSBvZmZzZXQgdG8gYXZvaWQgc2Nyb2xsaW5nIG9mZnNldCBjYXVzZWQgYnkgcGFnZSBzaHJpbmtcbiAgY29uc3QgY2xpZW50U3RhcnRYID0gZ2V0UG9pbnRlclBhZ2VYKHBvaW50ZXJEb3duRXZlbnQpO1xuICBjb25zdCBjbGllbnRTdGFydFkgPSBnZXRQb2ludGVyUGFnZVkocG9pbnRlckRvd25FdmVudCk7XG4gIGNvbnN0IGNsaWVudFggPSBnZXRQb2ludGVyUGFnZVgocG9pbnRlckRyYWdFdmVudCk7XG4gIGNvbnN0IGNsaWVudFkgPSBnZXRQb2ludGVyUGFnZVkocG9pbnRlckRyYWdFdmVudCk7XG5cbiAgLy8gZ2V0IHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIG1vdXNlRG93biBhbmQgb24tZmxpZ2h0IG1vdXNlRHJhZ2dpbmcuXG4gIGNvbnN0IHJlc2l6ZUVsZW1PZmZzZXRYID0gY2xpZW50WCAtIGNsaWVudFN0YXJ0WDtcbiAgY29uc3QgcmVzaXplRWxlbU9mZnNldFkgPSBjbGllbnRZIC0gY2xpZW50U3RhcnRZO1xuICBjb25zdCBkcmFnZ2luZ0VsZW1QcmV2SXRlbSA9IGNvbmZpZy5sYXlvdXQuZmluZChcbiAgICBpdGVtID0+IGl0ZW0uaWQgPT09IGdyaWRJdGVtSWQsXG4gICkhO1xuICBjb25zdCB3aWR0aCA9XG4gICAgZHJhZ0VsZW1DbGllbnRSZWN0LndpZHRoICsgcmVzaXplRWxlbU9mZnNldFggLSBzY3JvbGxEaWZmZXJlbmNlLmxlZnQ7XG4gIGNvbnN0IGhlaWdodCA9XG4gICAgZHJhZ0VsZW1DbGllbnRSZWN0LmhlaWdodCArIHJlc2l6ZUVsZW1PZmZzZXRZIC0gc2Nyb2xsRGlmZmVyZW5jZS50b3A7XG5cbiAgLy8gR2V0IGxheW91dCBpdGVtIGdyaWQgcG9zaXRpb25cbiAgY29uc3QgbGF5b3V0SXRlbTogR3JpZExheW91dEl0ZW0gPSB7XG4gICAgLi4uZHJhZ2dpbmdFbGVtUHJldkl0ZW0sXG4gICAgdzogc2NyZWVuV2lkdGhUb0dyaWRXaWR0aChcbiAgICAgIHdpZHRoLFxuICAgICAgY29uZmlnLmNvbHMsXG4gICAgICBncmlkRWxlbUNsaWVudFJlY3Qud2lkdGgsXG4gICAgICBjb25maWcuZ3V0dGVyLFxuICAgICksXG4gICAgaDogc2NyZWVuSGVpZ2h0VG9HcmlkSGVpZ2h0KGhlaWdodCwgY29uZmlnLnJvd0hlaWdodCwgY29uZmlnLmd1dHRlciksXG4gIH07XG5cbiAgbGF5b3V0SXRlbS53ID0gY2xhbXBTaXplKFxuICAgIGxheW91dEl0ZW0udyxcbiAgICBncmlkSXRlbS5taW5XID8/IGxheW91dEl0ZW0ubWluVyxcbiAgICBncmlkSXRlbS5tYXhXID8/IGxheW91dEl0ZW0ubWF4VyxcbiAgKTtcbiAgbGF5b3V0SXRlbS5oID0gY2xhbXBTaXplKFxuICAgIGxheW91dEl0ZW0uaCxcbiAgICBncmlkSXRlbS5taW5IID8/IGxheW91dEl0ZW0ubWluSCxcbiAgICBncmlkSXRlbS5tYXhIID8/IGxheW91dEl0ZW0ubWF4SCxcbiAgKTtcbiAgaWYgKGxheW91dEl0ZW0ueCArIGxheW91dEl0ZW0udyA+IGNvbmZpZy5jb2xzKSB7XG4gICAgbGF5b3V0SXRlbS53ID0gTWF0aC5tYXgoMSwgY29uZmlnLmNvbHMgLSBsYXlvdXRJdGVtLngpO1xuICB9XG5cbiAgaWYgKGNvbmZpZy5wcmV2ZW50Q29sbGlzaW9uKSB7XG4gICAgY29uc3QgbWF4VyA9IGxheW91dEl0ZW0udztcbiAgICBjb25zdCBtYXhIID0gbGF5b3V0SXRlbS5oO1xuXG4gICAgbGV0IGNvbGxpZGluZyA9IGhhc0NvbGxpc2lvbihjb25maWcubGF5b3V0LCBsYXlvdXRJdGVtKTtcbiAgICBsZXQgc2hydW5rRGltZW5zaW9uOiBHcmlkSXRlbURpbWVuc2lvbjtcblxuICAgIHdoaWxlIChjb2xsaWRpbmcpIHtcbiAgICAgIHNocnVua0RpbWVuc2lvbiA9IGdldFNocmlua0RpbWVuc2lvbihsYXlvdXRJdGVtLCBzaHJ1bmtEaW1lbnNpb24pO1xuICAgICAgbGF5b3V0SXRlbVtzaHJ1bmtEaW1lbnNpb25dLS07XG4gICAgICBjb2xsaWRpbmcgPSBoYXNDb2xsaXNpb24oY29uZmlnLmxheW91dCwgbGF5b3V0SXRlbSk7XG4gICAgfVxuXG4gICAgaWYgKHNocnVua0RpbWVuc2lvbiA9PT0gJ3cnKSB7XG4gICAgICBsYXlvdXRJdGVtLmggPSBtYXhIO1xuXG4gICAgICBjb2xsaWRpbmcgPSBoYXNDb2xsaXNpb24oY29uZmlnLmxheW91dCwgbGF5b3V0SXRlbSk7XG4gICAgICB3aGlsZSAoY29sbGlkaW5nKSB7XG4gICAgICAgIGxheW91dEl0ZW0uaC0tO1xuICAgICAgICBjb2xsaWRpbmcgPSBoYXNDb2xsaXNpb24oY29uZmlnLmxheW91dCwgbGF5b3V0SXRlbSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChzaHJ1bmtEaW1lbnNpb24gPT09ICdoJykge1xuICAgICAgbGF5b3V0SXRlbS53ID0gbWF4VztcblxuICAgICAgY29sbGlkaW5nID0gaGFzQ29sbGlzaW9uKGNvbmZpZy5sYXlvdXQsIGxheW91dEl0ZW0pO1xuICAgICAgd2hpbGUgKGNvbGxpZGluZykge1xuICAgICAgICBsYXlvdXRJdGVtLnctLTtcbiAgICAgICAgY29sbGlkaW5nID0gaGFzQ29sbGlzaW9uKGNvbmZpZy5sYXlvdXQsIGxheW91dEl0ZW0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBjb25zdCBuZXdMYXlvdXRJdGVtczogTGF5b3V0SXRlbVtdID0gY29uZmlnLmxheW91dC5tYXAoaXRlbSA9PlxuICAgIGl0ZW0uaWQgPT09IGdyaWRJdGVtSWQgPyBsYXlvdXRJdGVtIDogaXRlbSxcbiAgKTtcbiAgcmV0dXJuIHtcbiAgICBsYXlvdXQ6IGNvbXBhY3QobmV3TGF5b3V0SXRlbXMsIGNvbXBhY3RUeXBlLCBjb25maWcuY29scyksXG4gICAgZHJhZ2dlZEl0ZW1Qb3M6IHtcbiAgICAgIHRvcDogZHJhZ0VsZW1DbGllbnRSZWN0LnRvcCAtIGdyaWRFbGVtQ2xpZW50UmVjdC50b3AsXG4gICAgICBsZWZ0OiBkcmFnRWxlbUNsaWVudFJlY3QubGVmdCAtIGdyaWRFbGVtQ2xpZW50UmVjdC5sZWZ0LFxuICAgICAgLy8gd2hlbiB2ZXJ0aWNhbCwgbWFrZSBzdXJlIHJlc2l6aW5nIG5vdCBvdmVyZmxvdyByaWdodCBib3VuZGFyeVxuICAgICAgd2lkdGg6IGNsYW1wU2l6ZShcbiAgICAgICAgd2lkdGgsXG4gICAgICAgIDAsXG4gICAgICAgIGNvbXBhY3RUeXBlID09PSBHcmlkQ29tcGFjdFR5cGUuVkVSVElDQUxcbiAgICAgICAgICA/IChncmlkRWxlbUNsaWVudFJlY3Qud2lkdGggKiAoY29uZmlnLmNvbHMgLSBsYXlvdXRJdGVtLngpKSAvXG4gICAgICAgICAgICAgIGNvbmZpZy5jb2xzXG4gICAgICAgICAgOiBJbmZpbml0eSxcbiAgICAgICksXG4gICAgICBoZWlnaHQsXG4gICAgfSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gaGFzQ29sbGlzaW9uKGxheW91dDogTGF5b3V0LCBsYXlvdXRJdGVtOiBMYXlvdXRJdGVtKTogYm9vbGVhbiB7XG4gIHJldHVybiAhIWdldEZpcnN0Q29sbGlzaW9uKGxheW91dCwgbGF5b3V0SXRlbSk7XG59XG5cbmZ1bmN0aW9uIGdldFNocmlua0RpbWVuc2lvbihcbiAgbGF5b3V0SXRlbTogR3JpZExheW91dEl0ZW0sXG4gIGxhc3RTaHJ1bms6IEdyaWRJdGVtRGltZW5zaW9uLFxuKTogR3JpZEl0ZW1EaW1lbnNpb24ge1xuICBpZiAobGF5b3V0SXRlbS5oIDw9IDEpIHtcbiAgICByZXR1cm4gJ3cnO1xuICB9XG4gIGlmIChsYXlvdXRJdGVtLncgPD0gMSkge1xuICAgIHJldHVybiAnaCc7XG4gIH1cblxuICByZXR1cm4gbGFzdFNocnVuayA9PT0gJ3cnID8gJ2gnIDogJ3cnO1xufVxuXG4vKiogUmV0dXJucyB0cnVlIGlmIGJvdGggaXRlbTEgYW5kIGl0ZW0yIEdyaWRMYXlvdXRJdGVtcyBhcmUgZXF1aXZhbGVudC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0dyaWRJdGVtTGF5b3V0SXRlbUVxdWFsKFxuICBpdGVtMTogR3JpZExheW91dEl0ZW0sXG4gIGl0ZW0yOiBHcmlkTGF5b3V0SXRlbSxcbik6IGJvb2xlYW4ge1xuICByZXR1cm4gKFxuICAgIGl0ZW0xLmlkID09PSBpdGVtMi5pZCAmJlxuICAgIGl0ZW0xLnggPT09IGl0ZW0yLnggJiZcbiAgICBpdGVtMS55ID09PSBpdGVtMi55ICYmXG4gICAgaXRlbTEudyA9PT0gaXRlbTIudyAmJlxuICAgIGl0ZW0xLmggPT09IGl0ZW0yLmhcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEdyaWRIZWlnaHQoXG4gIGxheW91dDogR3JpZExheW91dCxcbiAgcm93SGVpZ2h0OiBudW1iZXIsXG4gIGd1dHRlcjogbnVtYmVyLFxuKTogbnVtYmVyIHtcbiAgcmV0dXJuIGxheW91dC5yZWR1Y2UoXG4gICAgKGFjYywgY3VyKSA9PlxuICAgICAgTWF0aC5tYXgoXG4gICAgICAgIGFjYyxcbiAgICAgICAgKGN1ci55ICsgY3VyLmgpICogcm93SGVpZ2h0ICsgTWF0aC5tYXgoY3VyLnkgKyBjdXIuaCAtIDEsIDApICogZ3V0dGVyLFxuICAgICAgKSxcbiAgICAwLFxuICApO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdldERyYWdSZXNpemVFdmVudERhdGEoXG4gIGdyaWRJdGVtOiBHcmlkSXRlbUNvbXBvbmVudCxcbiAgbGF5b3V0OiBHcmlkTGF5b3V0LFxuKTogRHJhZ1Jlc2l6ZUV2ZW50IHtcbiAgcmV0dXJuIHtcbiAgICBsYXlvdXQsXG4gICAgbGF5b3V0SXRlbTogbGF5b3V0LmZpbmQoaXRlbSA9PiBpdGVtLmlkID09PSBncmlkSXRlbS5pZCkhLFxuICAgIGdyaWRJdGVtUmVmOiBncmlkSXRlbSxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGxheW91dFRvUmVuZGVySXRlbXMoXG4gIGNvbmZpZzogR3JpZENmZyxcbiAgd2lkdGg6IG51bWJlcixcbiAgbGF5b3V0PzogR3JpZExheW91dCxcbik6IERpY3Rpb25hcnk8R3JpZEl0ZW1SZW5kZXJEYXRhPiB7XG4gIGNvbnN0IHsgY29scywgcm93SGVpZ2h0LCBsYXlvdXQ6IHJhd0xheW91dCwgZ3V0dGVyIH0gPSBjb25maWc7XG4gIGNvbnN0IHdpZHRoV2l0aG91dEd1dHRlciA9IHdpZHRoIC0gTWF0aC5tYXgoZ3V0dGVyICogKGNvbHMgLSAxKSwgMCk7XG4gIGNvbnN0IGl0ZW1XaWR0aFBlckNvbHVtbiA9IHdpZHRoV2l0aG91dEd1dHRlciAvIGNvbHM7XG4gIGNvbnN0IHJlbmRlckl0ZW1zOiBEaWN0aW9uYXJ5PEdyaWRJdGVtUmVuZGVyRGF0YT4gPSB7fTtcblxuICBmb3IgKGNvbnN0IGl0ZW0gb2YgbGF5b3V0ID8/IHJhd0xheW91dCkge1xuICAgIHJlbmRlckl0ZW1zW2l0ZW0uaWRdID0ge1xuICAgICAgaWQ6IGl0ZW0uaWQsXG4gICAgICB0b3A6IGl0ZW0ueSAqIHJvd0hlaWdodCArIGd1dHRlciAqIGl0ZW0ueSxcbiAgICAgIGxlZnQ6IGl0ZW0ueCAqIGl0ZW1XaWR0aFBlckNvbHVtbiArIGd1dHRlciAqIGl0ZW0ueCxcbiAgICAgIHdpZHRoOiBpdGVtLncgKiBpdGVtV2lkdGhQZXJDb2x1bW4gKyBndXR0ZXIgKiBNYXRoLm1heChpdGVtLncgLSAxLCAwKSxcbiAgICAgIGhlaWdodDogaXRlbS5oICogcm93SGVpZ2h0ICsgZ3V0dGVyICogTWF0aC5tYXgoaXRlbS5oIC0gMSwgMCksXG4gICAgfTtcbiAgfVxuICByZXR1cm4gcmVuZGVySXRlbXM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVJlbmRlckl0ZW1Ub1BpeGVscyhcbiAgcmVuZGVySXRlbTogR3JpZEl0ZW1SZW5kZXJEYXRhLFxuKTogR3JpZEl0ZW1SZW5kZXJEYXRhPHN0cmluZz4ge1xuICByZXR1cm4ge1xuICAgIGlkOiByZW5kZXJJdGVtLmlkLFxuICAgIHRvcDogYCR7cmVuZGVySXRlbS50b3B9cHhgLFxuICAgIGxlZnQ6IGAke3JlbmRlckl0ZW0ubGVmdH1weGAsXG4gICAgd2lkdGg6IGAke3JlbmRlckl0ZW0ud2lkdGh9cHhgLFxuICAgIGhlaWdodDogYCR7cmVuZGVySXRlbS5oZWlnaHR9cHhgLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29ycmVjdExheW91dChsYXlvdXQ6IEdyaWRMYXlvdXQsIGNvbHMgPSAxMikge1xuICByZXR1cm4gY29tcGFjdEdyaWRMYXlvdXQobGF5b3V0LCAndmVydGljYWwnLCBjb2xzKTtcbn1cbiJdfQ==