UNPKG

cytoscape-angular

Version:
197 lines 45.9 kB
import { FieldInfo, FieldsetInfo, FormInfo } from '../fluid-form/form-info'; class StyleFieldInfo extends FieldInfo { constructor(styleName, type, hint, options) { super(styleName, styleName, type, hint); this.options = options; } fieldType(model) { switch (this.type) { case 'percent': return 'number'; case 'ShapePolygonPoints': case 'NodeShape': case 'LineStyle': case 'TextTransformation': case 'FontStyle': case 'FontWeight': case 'Colour': return 'string'; default: return super.fieldType(model); } } } export function createStyleCoreFormInfo() { return new FormInfo('Core Styles', [ new FieldsetInfo('Background', [ new StyleFieldInfo('active-bg-color', 'Colour', 'The colour of the indicator shown when the background is grabbed by the user.'), new StyleFieldInfo('active-bg-opacity', 'number', 'The opacity of the active background indicator.'), new StyleFieldInfo('active-bg-size', 'number', 'The size of the active background indicator..') ]), new FieldsetInfo('Selection Box', [ new StyleFieldInfo('selection-box-color', 'Colour', 'The background colour of the selection box used for drag selection.'), new StyleFieldInfo('selection-box-border-color', 'Colour', 'The colour of the border of the selection box used for drag selection.'), new StyleFieldInfo('selection-box-border-width', 'number', 'The size of the border on the selection box.'), new StyleFieldInfo('selection-box-opacity', 'number', 'The opacity of the selection box.'), new StyleFieldInfo('', 'number', '') ]), new FieldsetInfo('Texture During Viewport Gestures', [ new StyleFieldInfo('outside-texture-bg-color', 'Colour', 'The colour of the area outside the viewport texture when initOptions.textureOnViewport === true.'), new StyleFieldInfo('outside-texture-bg-opacity', 'number', 'The opacity of the area outside the viewport texture.'), ]), ], false); } function fieldSorter(field1, field2) { if (!field1) { return field2 ? 1 : 0; } else if (!field2) { return -1; } else { const label1 = typeof field1.label === 'function' ? field1.label() : field1.label; const label2 = typeof field2.label === 'function' ? field2.label() : field2.label; return label1.localeCompare(label2); } } export function createStyleEdgeFieldSets() { const fieldsetInfos = []; return fieldsetInfos; } export function createStyleNodeFieldSets() { const fieldsetInfos = []; let nodeFieldInfos = []; nodeFieldInfos.push(new StyleFieldInfo('label', 'string', 'The text to display for an element’s label.')); nodeFieldInfos.push(new StyleFieldInfo('source-label', 'string', 'The text to display for a node’s source label.')); nodeFieldInfos.push(new StyleFieldInfo('target-label', 'string', 'The text to display for a node’s target label.')); nodeFieldInfos.push(new StyleFieldInfo('color', 'Colour', 'The colour of the element’s label.')); nodeFieldInfos.push(new StyleFieldInfo('font-family', 'string', 'A comma-separated list of font names to use on the label text.')); /** * https://developer.mozilla.org/en-US/docs/Web/CSS/font-family */ nodeFieldInfos.push(new StyleFieldInfo('font-size', 'string', 'The size of the label text.')); /** * https://developer.mozilla.org/en-US/docs/Web/CSS/font-style */ nodeFieldInfos.push(new StyleFieldInfo('font-style', 'FontStyle', 'A CSS font style to be applied to the label text.')); nodeFieldInfos.push(new StyleFieldInfo('font-weight', 'FontWeight', 'A CSS font weight to be applied to the label text.')); nodeFieldInfos.push(new StyleFieldInfo('text-max-width', 'string', 'The maximum width for wrapped text, applied when "text-wrap" is set to wrap. For only manual newlines (i.e.\\n), set a very large value like 1000px such that only your newline characters would apply.')); let textWrapStyleFieldInfo = new StyleFieldInfo('text-wrap', 'options', 'A wrapping style to apply to the label text; may be "none" for no wrapping (including manual newlines ) or "wrap" for manual and/ or autowrapping.'); textWrapStyleFieldInfo.options = [ { label: 'none', value: 'none' }, { label: 'wrap', value: 'wrap' }, { label: 'ellipsis', value: 'ellipsis' } ]; nodeFieldInfos.push(textWrapStyleFieldInfo); /** * Node label alignment: */ nodeFieldInfos.push(new StyleFieldInfo('text-halign', 'options', 'The vertical alignment of a node’s label.', [ { name: '', label: '' }, { label: 'left', value: 'left' }, { label: 'center', value: 'center' }, { labe: 'right', value: 'right' } ])); nodeFieldInfos.push(new StyleFieldInfo('text-valign', 'options', 'The vertical alignment of a node’s label.', [ { name: '', label: '' }, { label: 'top', value: 'top' }, { label: 'center', value: 'center' }, { label: 'bottom', value: 'bottom' } ])); nodeFieldInfos.push(new StyleFieldInfo('text-opacity', 'number', 'The opacity of the label text, including its outline.')); nodeFieldInfos.push(new StyleFieldInfo('text-transform', 'TextTransformation', 'A transformation to apply to the label text.')); fieldsetInfos.push(new FieldsetInfo('Label', nodeFieldInfos)); nodeFieldInfos = []; nodeFieldInfos.push(new StyleFieldInfo('content', 'string', 'The CSS content field')); nodeFieldInfos.push(new StyleFieldInfo('width', 'string', 'The width of the node’s body. This property can take on the special value label so the width is automatically based on the node’s label.')); nodeFieldInfos.push(new StyleFieldInfo('height', 'string', 'The height of the node’s body. This property can take on the special value label so the height is automatically based on the node’s label.')); nodeFieldInfos.push(new StyleFieldInfo('background-color', 'Colour', 'The colour of the node’s body.')); nodeFieldInfos.push(new StyleFieldInfo('background-blacken', 'number', ' Blackens the node’s body for values from 0 to 1; whitens the node’s body for values from 0 to -1.')); nodeFieldInfos.push(new StyleFieldInfo('background-opacity', 'number', 'The opacity level of the node’s background colour.')); nodeFieldInfos.push(new StyleFieldInfo('border-width', 'string', 'The size of the node’s border.')); nodeFieldInfos.push(new StyleFieldInfo('border-style', 'LineStyle', 'The style of the node’s border.')); nodeFieldInfos.push(new StyleFieldInfo('border-color', 'Colour', 'The colour of the node’s border.')); nodeFieldInfos.push(new StyleFieldInfo('border-opacity', 'percent', 'The opacity of the node’s border. A value between [0 1].')); nodeFieldInfos.push(new StyleFieldInfo('shape', 'NodeShape', 'The shape of the node’s body.')); nodeFieldInfos.push(new StyleFieldInfo('shape-polygon-points', 'ShapePolygonPoints', '')); nodeFieldInfos.push(new StyleFieldInfo('overlay-color', 'Colour', 'The colour of the overlay on top of nodes or edges.')); nodeFieldInfos.push(new StyleFieldInfo('overlay-padding', 'string', 'The area outside of the element within which the overlay is shown.')); nodeFieldInfos.push(new StyleFieldInfo('overlay-opacity', 'number', 'The opacity of the overlay.')); nodeFieldInfos.push(new StyleFieldInfo('padding-left', 'string', ' Padding increases node dimensions by adding spacing around the label of nodes whose heights and widths are the value \'label\', or it can be used to add spacing between a compound node parent and its children.')); nodeFieldInfos.push(new StyleFieldInfo('padding-right', 'string', ' Padding increases node dimensions by adding spacing around the label of nodes whose heights and widths are the value \'label\', or it can be used to add spacing between a compound node parent and its children.')); nodeFieldInfos.push(new StyleFieldInfo('padding-top', 'string', ' Padding increases node dimensions by adding spacing around the label of nodes whose heights and widths are the value \'label\', or it can be used to add spacing between a compound node parent and its children.')); nodeFieldInfos.push(new StyleFieldInfo('padding-bottom', 'string', ' Padding increases node dimensions by adding spacing around the label of nodes whose heights and widths are the value \'label\', or it can be used to add spacing between a compound node parent and its children.')); fieldsetInfos.push(new FieldsetInfo('Node', nodeFieldInfos)); nodeFieldInfos = []; /** * Edge label alignment: */ nodeFieldInfos.push(new StyleFieldInfo('source-text-offset', 'number', 'For the source label of an edge, how far from the source node the label should be placed.')); nodeFieldInfos.push(new StyleFieldInfo('target-text-offset', 'number', 'For the target label of an edge, how far from the target node the label should be placed.')); /** * Margins: */ nodeFieldInfos.push(new StyleFieldInfo('text-margin-x', 'number', 'A margin that shifts the label along the x- axis.')); nodeFieldInfos.push(new StyleFieldInfo('text-margin-y', 'number', 'A margin that shifts the label along the y- axis.')); nodeFieldInfos.push(new StyleFieldInfo('source-text-margin-x', 'number', '(For the source label of an edge.)')); nodeFieldInfos.push(new StyleFieldInfo('source-text-margin-y', 'number', '(For the source label of an edge.)')); nodeFieldInfos.push(new StyleFieldInfo('target-text-margin-x', 'number', '(For the target label of an edge.)')); nodeFieldInfos.push(new StyleFieldInfo('target-text-margin-y', 'number', '(For the target label of an edge.)')); /** * Rotating text: */ nodeFieldInfos.push(new StyleFieldInfo('text-rotation', 'number', 'A rotation angle that is applied to the label. For edges, the special value autorotate can be used to align the label to the edge. For nodes, the label is rotated along its anchor point on the node, so a label margin may help for some usecases. The special value none can be used to denote 0deg. Rotations works best with left- to - right text.')); nodeFieldInfos.push(new StyleFieldInfo('source-text-rotation', 'number', '(For the source label of an edge.)')); nodeFieldInfos.push(new StyleFieldInfo('target-text-rotation', 'number', '(For the target label of an edge.)')); /** * Outline: */ nodeFieldInfos.push(new StyleFieldInfo('text-outline-color', 'Colour', 'The colour of the outline around the element’s label text.')); nodeFieldInfos.push(new StyleFieldInfo('text-outline-opacity', 'number', 'The opacity of the outline on label text.')); nodeFieldInfos.push(new StyleFieldInfo('text-outline-width', 'string', 'The size of the outline on label text.')); /** * Shadow: */ nodeFieldInfos.push(new StyleFieldInfo('text-shadow-blur', 'number', 'The shadow blur distance.')); nodeFieldInfos.push(new StyleFieldInfo('text-shadow-color', 'Colour', 'The colour of the shadow.')); nodeFieldInfos.push(new StyleFieldInfo('text-shadow-offset-x', 'number', 'The x offset relative to the text where the shadow will be displayed, can be negative. If you set blur to 0, add an offset to view your shadow.')); nodeFieldInfos.push(new StyleFieldInfo('text-shadow-offset-y', 'number', 'The y offset relative to the text where the shadow will be displayed, can be negative. If you set blur to 0, add an offset to view your shadow.')); nodeFieldInfos.push(new StyleFieldInfo('text-shadow-opacity', 'number', 'The opacity of the shadow on the text; the shadow is disabled for 0 (default value).')); /** * Background: */ nodeFieldInfos.push(new StyleFieldInfo('text-background-padding', 'string', 'The padding provides visual spacing between the text and the edge of the background.')); nodeFieldInfos.push(new StyleFieldInfo('text-background-color', 'Colour', 'A colour to apply on the text background.')); nodeFieldInfos.push(new StyleFieldInfo('text-background-opacity', 'number', 'The opacity of the label background; the background is disabled for 0 (default value).')); nodeFieldInfos.push(new StyleFieldInfo('text-background-shape', 'options', 'The shape to use for the label background.', [ { name: '', label: '' }, { label: 'rectangle', value: 'rectangle' }, { label: 'roundrectangle', value: 'roundrectangle' } ])); nodeFieldInfos.push(new StyleFieldInfo('text-border-opacity', 'number', 'The width of the border around the label; the border is disabled for 0 (default value).')); nodeFieldInfos.push(new StyleFieldInfo('text-border-width', 'number', 'The width of the border around the label.')); nodeFieldInfos.push(new StyleFieldInfo('text-border-style', 'LineStyle', 'The style of the border around the label.')); nodeFieldInfos.push(new StyleFieldInfo('text-border-color', 'Colour', 'The colour of the border around the label.')); fieldsetInfos.push(new FieldsetInfo('Advanced Text', nodeFieldInfos)); nodeFieldInfos = []; /** * Interactivity: */ nodeFieldInfos.push(new StyleFieldInfo('min-zoomed-font-size', 'number', 'If zooming makes the effective font size of the label smaller than this, then no label is shown.Note that because of performance optimisations, the label may be shown at font sizes slightly smaller than this value. This effect is more pronounced at larger screen pixel ratios. However, it is guaranteed that the label will be shown at sizes equal to or greater than the value specified.')); nodeFieldInfos.push(new StyleFieldInfo('text-events', 'options', 'Whether events should occur on an element if the label receives an event. You may want a style applied to the text onactive so you know the text is activatable.', [ { label: 'yes', value: 'yes' }, { label: 'no', value: 'no' } ])); fieldsetInfos.push(new FieldsetInfo('Interactivity', nodeFieldInfos)); return fieldsetInfos; } /** * Defaults to a blank node */ export class StylesheetImpl { constructor(selector = 'node', style = {}) { this.selector = selector; this.style = style; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3R5bGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jeXRvc2NhcGUtYW5ndWxhci9zcmMvbGliL3N0eWxlL3N0eWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFhLFFBQVEsRUFBRSxNQUFNLHlCQUF5QixDQUFBO0FBRXRGLE1BQU0sY0FBZSxTQUFRLFNBQVM7SUFDcEMsWUFBWSxTQUFpQixFQUFFLElBQWUsRUFBRSxJQUFZLEVBQUUsT0FBMkI7UUFDdkYsS0FBSyxDQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFBO1FBQ3ZDLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFBO0lBQ3hCLENBQUM7SUFFRCxTQUFTLENBQUMsS0FBYTtRQUNyQixRQUFRLElBQUksQ0FBQyxJQUFJLEVBQUU7WUFDakIsS0FBSyxTQUFTO2dCQUNaLE9BQU8sUUFBUSxDQUFBO1lBQ2pCLEtBQUssb0JBQW9CLENBQUM7WUFDMUIsS0FBSyxXQUFXLENBQUM7WUFDakIsS0FBSyxXQUFXLENBQUM7WUFDakIsS0FBSyxvQkFBb0IsQ0FBQztZQUMxQixLQUFLLFdBQVcsQ0FBQztZQUNqQixLQUFLLFlBQVksQ0FBQztZQUNsQixLQUFLLFFBQVE7Z0JBQ1gsT0FBTyxRQUFRLENBQUE7WUFDakI7Z0JBQ0UsT0FBTyxLQUFLLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFBO1NBQ2hDO0lBQ0gsQ0FBQztDQUNGO0FBRUQsTUFBTSxVQUFVLHVCQUF1QjtJQUNyQyxPQUFPLElBQUksUUFBUSxDQUFDLGFBQWEsRUFDL0I7UUFDRSxJQUFJLFlBQVksQ0FBQyxZQUFZLEVBQUU7WUFDN0IsSUFBSSxjQUFjLENBQUMsaUJBQWlCLEVBQUUsUUFBUSxFQUM1QywrRUFBK0UsQ0FBQztZQUNsRixJQUFJLGNBQWMsQ0FBQyxtQkFBbUIsRUFBRSxR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dHlsZSB9IGZyb20gJ2N5dG9zY2FwZSdcbmltcG9ydCB7IEZpZWxkSW5mbywgRmllbGRzZXRJbmZvLCBGaWVsZFR5cGUsIEZvcm1JbmZvIH0gZnJvbSAnLi4vZmx1aWQtZm9ybS9mb3JtLWluZm8nXG5cbmNsYXNzIFN0eWxlRmllbGRJbmZvIGV4dGVuZHMgRmllbGRJbmZvIHtcbiAgY29uc3RydWN0b3Ioc3R5bGVOYW1lOiBzdHJpbmcsIHR5cGU6IEZpZWxkVHlwZSwgaGludDogc3RyaW5nLCBvcHRpb25zPzogb2JqZWN0W10gfCBzdHJpbmcpIHtcbiAgICBzdXBlcihzdHlsZU5hbWUsIHN0eWxlTmFtZSwgdHlwZSwgaGludClcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zXG4gIH1cblxuICBmaWVsZFR5cGUobW9kZWw6IG9iamVjdCk6IEZpZWxkVHlwZSB7XG4gICAgc3dpdGNoICh0aGlzLnR5cGUpIHtcbiAgICAgIGNhc2UgJ3BlcmNlbnQnIDpcbiAgICAgICAgcmV0dXJuICdudW1iZXInXG4gICAgICBjYXNlICdTaGFwZVBvbHlnb25Qb2ludHMnOlxuICAgICAgY2FzZSAnTm9kZVNoYXBlJzpcbiAgICAgIGNhc2UgJ0xpbmVTdHlsZSc6XG4gICAgICBjYXNlICdUZXh0VHJhbnNmb3JtYXRpb24nOlxuICAgICAgY2FzZSAnRm9udFN0eWxlJzpcbiAgICAgIGNhc2UgJ0ZvbnRXZWlnaHQnOlxuICAgICAgY2FzZSAnQ29sb3VyJzpcbiAgICAgICAgcmV0dXJuICdzdHJpbmcnXG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gc3VwZXIuZmllbGRUeXBlKG1vZGVsKVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlU3R5bGVDb3JlRm9ybUluZm8oKSB7XG4gIHJldHVybiBuZXcgRm9ybUluZm8oJ0NvcmUgU3R5bGVzJyxcbiAgICBbXG4gICAgICBuZXcgRmllbGRzZXRJbmZvKCdCYWNrZ3JvdW5kJywgW1xuICAgICAgICBuZXcgU3R5bGVGaWVsZEluZm8oJ2FjdGl2ZS1iZy1jb2xvcicsICdDb2xvdXInLFxuICAgICAgICAgICdUaGUgY29sb3VyIG9mIHRoZSBpbmRpY2F0b3Igc2hvd24gd2hlbiB0aGUgYmFja2dyb3VuZCBpcyBncmFiYmVkIGJ5IHRoZSB1c2VyLicpLFxuICAgICAgICBuZXcgU3R5bGVGaWVsZEluZm8oJ2FjdGl2ZS1iZy1vcGFjaXR5JywgJ251bWJlcicsXG4gICAgICAgICAgJ1RoZSBvcGFjaXR5IG9mIHRoZSBhY3RpdmUgYmFja2dyb3VuZCBpbmRpY2F0b3IuJyksXG4gICAgICAgIG5ldyBTdHlsZUZpZWxkSW5mbygnYWN0aXZlLWJnLXNpemUnLCAnbnVtYmVyJyxcbiAgICAgICAgICAnVGhlIHNpemUgb2YgdGhlIGFjdGl2ZSBiYWNrZ3JvdW5kIGluZGljYXRvci4uJylcbiAgICAgIF0pLFxuXG4gICAgICBuZXcgRmllbGRzZXRJbmZvKCdTZWxlY3Rpb24gQm94JywgW1xuICAgICAgICBuZXcgU3R5bGVGaWVsZEluZm8oJ3NlbGVjdGlvbi1ib3gtY29sb3InLCAnQ29sb3VyJyxcbiAgICAgICAgICAnVGhlIGJhY2tncm91bmQgY29sb3VyIG9mIHRoZSBzZWxlY3Rpb24gYm94IHVzZWQgZm9yIGRyYWcgc2VsZWN0aW9uLicpLFxuICAgICAgICAgIG5ldyBTdHlsZUZpZWxkSW5mbygnc2VsZWN0aW9uLWJveC1ib3JkZXItY29sb3InLCAnQ29sb3VyJyxcbiAgICAgICAgICAgICdUaGUgY29sb3VyIG9mIHRoZSBib3JkZXIgb2YgdGhlIHNlbGVjdGlvbiBib3ggdXNlZCBmb3IgZHJhZyBzZWxlY3Rpb24uJyksXG4gICAgICAgICAgbmV3IFN0eWxlRmllbGRJbmZvKCdzZWxlY3Rpb24tYm94LWJvcmRlci13aWR0aCcsICdudW1iZXInLFxuICAgICAgICAgICAgJ1RoZSBzaXplIG9mIHRoZSBib3JkZXIgb24gdGhlIHNlbGVjdGlvbiBib3guJyksXG4gICAgICAgICAgbmV3IFN0eWxlRmllbGRJbmZvKCdzZWxlY3Rpb24tYm94LW9wYWNpdHknLCAnbnVtYmVyJyxcbiAgICAgICAgICAnVGhlIG9wYWNpdHkgb2YgdGhlIHNlbGVjdGlvbiBib3guJyksXG4gICAgICAgIG5ldyBTdHlsZUZpZWxkSW5mbygnJywgJ251bWJlcicsXG4gICAgICAgICAgJycpXG4gICAgICBdKSxcbiAgICAgIG5ldyBGaWVsZHNldEluZm8oJ1RleHR1cmUgRHVyaW5nIFZpZXdwb3J0IEdlc3R1cmVzJywgW1xuICAgICAgICBuZXcgU3R5bGVGaWVsZEluZm8oJ291dHNpZGUtdGV4dHVyZS1iZy1jb2xvcicsICdDb2xvdXInLFxuICAgICAgICAgICdUaGUgY29sb3VyIG9mIHRoZSBhcmVhIG91dHNpZGUgdGhlIHZpZXdwb3J0IHRleHR1cmUgd2hlbiBpbml0T3B0aW9ucy50ZXh0dXJlT25WaWV3cG9ydCA9PT0gdHJ1ZS4nKSxcbiAgICAgICAgbmV3IFN0eWxlRmllbGRJbmZvKCdvdXRzaWRlLXRleHR1cmUtYmctb3BhY2l0eScsICdudW1iZXInLFxuICAgICAgICAgICdUaGUgb3BhY2l0eSBvZiB0aGUgYXJlYSBvdXRzaWRlIHRoZSB2aWV3cG9ydCB0ZXh0dXJlLicpLFxuICAgICAgXSksXG4gICAgXSwgZmFsc2UpXG59XG5cbmZ1bmN0aW9uIGZpZWxkU29ydGVyKGZpZWxkMTogRmllbGRJbmZvLCBmaWVsZDI6IEZpZWxkSW5mbyk6IG51bWJlciB7XG4gIGlmICghZmllbGQxKSB7XG4gICAgcmV0dXJuIGZpZWxkMiA/IDE6IDBcbiAgfSBlbHNlIGlmICghZmllbGQyKSB7XG4gICAgcmV0dXJuIC0xXG4gIH0gZWxzZSB7XG4gICAgY29uc3QgbGFiZWwxID0gdHlwZW9mIGZpZWxkMS5sYWJlbCA9PT0gJ2Z1bmN0aW9uJyA/IGZpZWxkMS5sYWJlbCgpIDogZmllbGQxLmxhYmVsXG4gICAgY29uc3QgbGFiZWwyID0gdHlwZW9mIGZpZWxkMi5sYWJlbCA9PT0gJ2Z1bmN0aW9uJyA/IGZpZWxkMi5sYWJlbCgpIDogZmllbGQyLmxhYmVsXG4gICAgcmV0dXJuIGxhYmVsMS5sb2NhbGVDb21wYXJlKGxhYmVsMik7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVN0eWxlRWRnZUZpZWxkU2V0cygpIHtcbiAgY29uc3QgZmllbGRzZXRJbmZvczogRmllbGRzZXRJbmZvW10gPSBbXVxuICByZXR1cm4gZmllbGRzZXRJbmZvc1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlU3R5bGVOb2RlRmllbGRTZXRzKCkge1xuICBjb25zdCBmaWVsZHNldEluZm9zOiBGaWVsZHNldEluZm9bXSA9IFtdXG5cbiAgbGV0IG5vZGVGaWVsZEluZm9zOiBGaWVsZEluZm9bXSA9IFtdXG4gIG5vZGVGaWVsZEluZm9zLnB1c2gobmV3IFN0eWxlRmllbGRJbmZvKCdsYWJlbCcsICdzdHJpbmcnLCAnVGhlIHRleHQgdG8gZGlzcGxheSBmb3IgYW4gZWxlbWVudOKAmXMgbGFiZWwuJykpXG4gIG5vZGVGaWVsZEluZm9zLnB1c2gobmV3IFN0eWxlRmllbGRJbmZvKCdzb3VyY2UtbGFiZWwnLCAnc3RyaW5nJywgJ1RoZSB0ZXh0IHRvIGRpc3BsYXkgZm9yIGEgbm9kZeKAmXMgc291cmNlIGxhYmVsLicpKVxuICBub2RlRmllbGRJbmZvcy5wdXNoKG5ldyBTdHlsZUZpZWxkSW5mbygndGFyZ2V0LWxhYmVsJywgJ3N0cmluZycsICdUaGUgdGV4dCB0byBkaXNwbGF5IGZvciBhIG5vZGXigJlzIHRhcmdldCBsYWJlbC4nKSlcbiAgbm9kZUZpZWxkSW5mb3MucHVzaChuZXcgU3R5bGVGaWVsZEluZm8oJ2NvbG9yJywgJ0NvbG91cicsICdUaGUgY29sb3VyIG9mIHRoZSBlbGVtZW504oCZcyBsYWJlbC4nKSlcbiAgbm9kZUZpZWxkSW5mb3MucHVzaChuZXcgU3R5bGVGaWVsZEluZm8oJ2ZvbnQtZmFtaWx5JywgJ3N0cmluZycsICdBIGNvbW1hLXNlcGFyYXRlZCBsaXN0IG9mIGZvbnQgbmFtZXMgdG8gdXNlIG9uIHRoZSBsYWJlbCB0ZXh0LicpKVxuICAvKipcbiAgICogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTL2ZvbnQtZmFtaWx5XG4gICAqL1xuICBub2RlRmllbGRJbmZvcy5wdXNoKG5ldyBTdHlsZUZpZWxkSW5mbygnZm9udC1zaXplJywgJ3N0cmluZycsICdUaGUgc2l6ZSBvZiB0aGUgbGFiZWwgdGV4dC4nKSlcbiAgLyoqXG4gICAqIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0NTUy9mb250LXN0eWxlXG4gICAqL1xuICBub2RlRmllbGRJbmZvcy5wdXNoKG5ldyBTdHlsZUZpZWxkSW5mbygnZm9udC1zdHlsZScsICdGb250U3R5bGUnLCAnQSBDU1MgZm9udCBzdHlsZSB0byBiZSBhcHBsaWVkIHRvIHRoZSBsYWJlbCB0ZXh0LicpKVxuICBub2RlRmllbGRJbmZvcy5wdXNoKG5ldyBTdHlsZUZpZWxkSW5mbygnZm9udC13ZWlnaHQnLCAnRm9udFdlaWdodCcsICdBIENTUyBmb250IHdlaWdodCB0byBiZSBhcHBsaWVkIHRvIHRoZSBsYWJlbCB0ZXh0LicpKVxuICBub2RlRmllbGRJbmZvcy5wdXNoKG5ldyBTdHlsZUZpZWxkSW5mbygndGV4dC1tYXgtd2lkdGgnLCAnc3RyaW5nJywgJ1RoZSBtYXhpbXVtIHdpZHRoIGZvciB3cmFwcGVkIHRleHQsIGFwcGxpZWQgd2hlbiBcInRleHQtd3JhcFwiIGlzIHNldCB0byB3cmFwLiBGb3Igb25seSBtYW51YWwgbmV3bGluZXMgKGkuZS5cXFxcbiksIHNldCBhIHZlcnkgbGFyZ2UgdmFsdWUgbGlrZSAxMDAwcHggc3VjaCB0aGF0IG9ubHkgeW91ciBuZXdsaW5lIGNoYXJhY3RlcnMgd291bGQgYXBwbHkuJykpXG4gIGxldCB0ZXh0V3JhcFN0eWxlRmllbGRJbmZvID0gbmV3IFN0eWxlRmllbGRJbmZvKCd0ZXh0LXdyYXAnLCAnb3B0aW9ucycsXG4gICAgJ0Egd3JhcHBpbmcgc3R5bGUgdG8gYXBwbHkgdG8gdGhlIGxhYmVsIHRleHQ7IG1heSBiZSBcIm5vbmVcIiBmb3Igbm8gd3JhcHBpbmcgKGluY2x1ZGluZyBtYW51YWwgbmV3bGluZXMgKSBvciBcIndyYXBcIiBmb3IgbWFudWFsIGFuZC8gb3IgYXV0b3dyYXBwaW5nLicpXG4gIHRleHRXcmFwU3R5bGVGaWVsZEluZm8ub3B0aW9ucyA9IFtcbiAgICB7bGFiZWw6ICdub25lJywgdmFsdWU6ICdub25lJ30sXG4gICAge2xhYmVsOiAnd3JhcCcsIHZhbHVlOiAnd3JhcCd9LFxuICAgIHtsYWJlbDogJ2VsbGlwc2lzJywgdmFsdWU6ICdlbGxpcHNpcyd9XG4gICAgXVxuICBub2RlRmllbGRJbmZvcy5wdXNoKHRleHRXcmFwU3R5bGVGaWVsZEluZm8pXG4gIC8qKlxuICAgKiBOb2RlIGxhYmVsIGFsaWdubWVudDpcbiAgICovXG4gIG5vZGVGaWVsZEluZm9zLnB1c2gobmV3IFN0eWxlRmllbGRJbmZvKCd0ZXh0LWhhbGlnbicsICdvcHRpb25zJyxcbiAgICAnVGhlIHZlcnRpY2FsIGFsaWdubWVudCBvZiBhIG5vZGXigJlzIGxhYmVsLicsIFtcbiAgICAgIHtuYW1lOiAnJywgbGFiZWw6ICcnfSxcbiAgICAgIHtsYWJlbDogJ2xlZnQnLCB2YWx1ZTogJ2xlZnQnfSxcbiAgICAgIHtsYWJlbDogJ2NlbnRlcicsIHZhbHVlOiAnY2VudGVyJ30sXG4gICAgICB7bGFiZTogJ3JpZ2h0JywgdmFsdWU6ICdyaWdodCd9XSkpXG4gIG5vZGVGaWVsZEluZm9zLnB1c2gobmV3IFN0eWxlRmllbGRJbmZvKCd0ZXh0LXZhbGlnbicsICdvcHRpb25zJyxcbiAgICAnVGhlIHZlcnRpY2FsIGFsaWdubWVudCBvZiBhIG5vZGXigJlzIGxhYmVsLicsIFtcbiAgICAgIHtuYW1lOiAnJywgbGFiZWw6ICcnfSxcbiAgICAgIHtsYWJlbDogJ3RvcCcsIHZhbHVlOiAndG9wJ30sXG4gICAgICB7bGFiZWw6ICdjZW50ZXInLCB2YWx1ZTogJ2NlbnRlcid9LFxuICAgICAge2xhYmVsOiAnYm90dG9tJywgdmFsdWU6ICdib3R0b20nfV0pKVxuICBub2RlRmllbGRJbmZvcy5wdXNoKG5ldyBTdHlsZUZpZWxkSW5mbygndGV4dC1vcGFjaXR5JywgJ251bWJlcicsICdUaGUgb3BhY2l0eSBvZiB0aGUgbGFiZWwgdGV4dCwgaW5jbHVkaW5nIGl0cyBvdXRsaW5lLicpKVxuICBub2RlRmllbGRJbmZvcy5wdXNoKG5ldyBTdHlsZUZpZWxkSW5mbygndGV4dC10cmFuc2Zvcm0nLCAnVGV4dFRyYW5zZm9ybWF0aW9uJywgJ0EgdHJhbnNmb3JtYXRpb24gdG8gYXBwbHkgdG8gdGhlIGxhYmVsIHRleHQuJykpXG4gIGZpZWxkc2V0SW5mb3MucHVzaChuZXcgRmllbGRzZXRJbmZvKCdMYWJlbCcsIG5vZGVGaWVsZEluZm9zKSlcbiAgbm9kZUZpZWxkSW5mb3MgPSBbXVxuXG4gIG5vZGVGaWVsZEluZm9zLnB1c2gobmV3IFN0eWxlRmllbGRJbmZvKCdjb250ZW50JywgJ3N0cmluZycsICdUaGUgQ1NTIGNvbnRlbnQgZmllbGQnKSlcbiAgbm9kZUZpZWxkSW5mb3MucHVzaChuZXcgU3R5bGVGaWVsZEluZm8oJ3dpZHRoJywgJ3N0cmluZycsICdUaGUgd2lkdGggb2YgdGhlIG5vZGXigJlzIGJvZHkuIFRoaXMgcHJvcGVydHkgY2FuIHRha2Ugb24gdGhlIHNwZWNpYWwgdmFsdWUgbGFiZWwgc28gdGhlIHdpZHRoIGlzIGF1dG9tYXRpY2FsbHkgYmFzZWQgb24gdGhlIG5vZGXigJlzIGxhYmVsLicpKVxuICBub2RlRmllbGRJbmZvcy5wdXNoKG5ldyBTdHlsZUZpZWxkSW5mbygnaGVpZ2h0JywgJ3N0cmluZycsICdUaGUgaGVpZ2h0IG9mIHRoZSBub2Rl4oCZcyBib2R5LiBUaGlzIHByb3BlcnR5IGNhbiB0YWtlIG9uIHRoZSBzcGVjaWFsIHZhbHVlIGxhYmVsIHNvIHRoZSBoZWlnaHQgaXMgYXV0b21hdGljYWxseSBiYXNlZCBvbiB0aGUgbm9kZeKAmXMgbGFiZWwuJykpXG4gIG5vZGVGaWVsZEluZm9zLnB1c2gobmV3IFN0eWxlRmllbGRJbmZvKCdiYWNrZ3JvdW5kLWNvbG9yJywgJ0NvbG91cicsICdUaGUgY29sb3VyIG9mIHRoZSBub2Rl4oCZcyBib2R5LicpKVxuICBub2RlRmllbGRJbmZvcy5wdXNoKG5ldyBTdHlsZUZpZWxkSW5mbygnYmFja2dyb3VuZC1ibGFja2VuJywgJ251bWJlcicsICcgICBCbGFja2VucyB0aGUgbm9kZeKAmXMgYm9keSBmb3IgdmFsdWVzIGZyb20gMCB0byAxOyB3aGl0ZW5zIHRoZSBub2Rl4oCZcyBib2R5IGZvciB2YWx1ZXMgZnJvbSAwIHRvIC0xLicpKVxuICBub2RlRmllbGRJbmZvcy5wdXNoKG5ldyBTdHlsZUZpZWxkSW5mbygnYmFja2dyb3VuZC1vcGFjaXR5JywgJ251bWJlcicsICdUaGUgb3BhY2l0eSBsZXZlbCBvZiB0aGUgbm9kZeKAmXMgYmFja2dyb3VuZCBjb2xvdXIuJykpXG4gIG5vZGVGaWVsZEluZm9zLnB1c2gobmV3IFN0eWxlRmllbGRJbmZvKCdib3JkZXItd2lkdGgnLCAnc3RyaW5nJywgJ1RoZSBzaXplIG9mIHRoZSBub2Rl4oCZcyBib3JkZXIuJykpXG4gIG5vZGVGaWVsZEluZm9zLnB1c2gobmV3IFN0eWxlRmllbGRJbmZvKCdib3JkZXItc3R5bGUnLCAnTGluZVN0eWxlJywgJ1RoZSBzdHlsZSBvZiB0aGUgbm9kZeKAmXMgYm9yZGVyLicpKVxuICBub2RlRmllbGRJbmZvcy5wdXNoKG5ldyBTdHlsZUZpZWxkSW5mbygnYm9yZGVyLWNvbG9yJywgJ0NvbG91cicsICdUaGUgY29sb3VyIG9mIHRoZSBub2Rl4oCZcyBib3JkZXIuJykpXG4gIG5vZGVGaWVsZEluZm9zLnB1c2gobmV3IFN0eWxlRmllbGRJbmZvKCdib3JkZXItb3BhY2l0eScsICdwZXJjZW50JywgJ1RoZSBvcGFjaXR5IG9mIHRoZSBub2Rl4oCZcyBib3JkZXIuIEEgdmFsdWUgYmV0d2VlbiBbMCAxXS4nKSlcbiAgbm9kZUZpZWxkSW5mb3MucHVzaChuZXcgU3R5bGVGaWVsZEluZm8oJ3NoYXBlJywgJ05vZGVTaGFwZScsICdUaGUgc2hhcGUgb2YgdGhlIG5vZGXigJlzIGJvZHkuJykpXG4gIG5vZGVGaWVsZEluZm9zLnB1c2gobmV3IFN0eWxlRmllbGRJbmZvKCdzaGFwZS1wb2x5Z29uLXBvaW50cycsICdTaGFwZVBvbHlnb25Qb2ludHMnLCAnJykpXG4gIG5vZGVGaWVsZEluZm9zLnB1c2gobmV3IFN0eWxlRmllbGRJbmZvKCdvdmVybGF5LWNvbG9yJywgJ0NvbG91cicsICdUaGUgY29sb3VyIG9mIHRoZSBvdmVybGF5IG9uIHRvcCBvZiBub2RlcyBvciBlZGdlcy4nKSlcbiAgbm9kZUZpZWxkSW5mb3MucHVzaChuZXcgU3R5bGVGaWVsZEluZm8oJ292ZXJsYXktcGFkZGluZycsICdzdHJpbmcnLCAnVGhlIGFyZWEgb3V0c2lkZSBvZiB0aGUgZWxlbWVudCB3aXRoaW4gd2hpY2ggdGhlIG92ZXJsYXkgaXMgc2hvd24uJykpXG4gIG5vZGVGaWVsZEluZm9zLnB1c2gobmV3IFN0eWxlRmllbGRJbmZvKCdvdmVybGF5LW9wYWNpdHknLCAnbnVtYmVyJywgJ1RoZSBvcGFjaXR5IG9mIHRoZSBvdmVybGF5LicpKVxuICBub2RlRmllbGRJbmZvcy5wdXNoKG5ldyBTdHlsZUZpZWxkSW5mbygncGFkZGluZy1sZWZ0JywgJ3N0cmluZycsICcgICBQYWRkaW5nIGluY3JlYXNlcyBub2RlIGRpbWVuc2lvbnMgYnkgYWRkaW5nIHNwYWNpbmcgYXJvdW5kIHRoZSBsYWJlbCBvZiBub2RlcyB3aG9zZSBoZWlnaHRzIGFuZCB3aWR0aHMgYXJlIHRoZSB2YWx1ZSBcXCdsYWJlbFxcJywgb3IgaXQgY2FuIGJlIHVzZWQgdG8gYWRkIHNwYWNpbmcgYmV0d2VlbiBhIGNvbXBvdW5kIG5vZGUgcGFyZW50IGFuZCBpdHMgY2hpbGRyZW4uJykpXG4gIG5vZGVGaWVsZEluZm9zLnB1c2gobmV3IFN0eWxlRmllbGRJbmZvKCdwYWRkaW5nLXJpZ2h0JywgJ3N0cmluZycsICcgICBQYWRkaW5nIGluY3JlYXNlcyBub2RlIGRpbWVuc2lvbnMgYnkgYWRkaW5nIHNwYWNpbmcgYXJvdW5kIHRoZSBsYWJlbCBvZiBub2RlcyB3aG9zZSBoZWlnaHRzIGFuZCB3aWR0aHMgYXJlIHRoZSB2YWx1ZSBcXCdsYWJlbFxcJywgb3IgaXQgY2FuIGJlIHVzZWQgdG8gYWRkIHNwYWNpbmcgYmV0d2VlbiBhIGNvbXBvdW5kIG5vZGUgcGFyZW50IGFuZCBpdHMgY2hpbGRyZW4uJykpXG4gIG5vZGVGaWVsZEluZm9zLnB1c2gobmV3IFN0eWxlRmllbGRJbmZvKCdwYWRkaW5nLXRvcCcsICdzdHJpbmcnLCAnICAgUGFkZGluZyBpbmNyZWFzZXMgbm9kZSBkaW1lbnNpb25zIGJ5IGFkZGluZyBzcGFjaW5nIGFyb3VuZCB0aGUgbGFiZWwgb2Ygbm9kZXMgd2hvc2UgaGVpZ2h0cyBhbmQgd2lkdGhzIGFyZSB0aGUgdmFsdWUgXFwnbGFiZWxcXCcsIG9yIGl0IGNhbiBiZSB1c2VkIHRvIGFkZCBzcGFjaW5nIGJldHdlZW4gYSBjb21wb3VuZCBub2RlIHBhcmVudCBhbmQgaXRzIGNoaWxkcmVuLicpKVxuICBub2RlRmllbGRJbmZvcy5wdXNoKG5ldyBTdHlsZUZpZWxkSW5mbygncGFkZGluZy1ib3R0b20nLCAnc3RyaW5nJywgJyAgIFBhZGRpbmcgaW5jcmVhc2VzIG5vZGUgZGltZW5zaW9ucyBieSBhZGRpbmcgc3BhY2luZyBhcm91bmQgdGhlIGxhYmVsIG9mIG5vZGVzIHdob3NlIGhlaWdodHMgYW5kIHdpZHRocyBhcmUgdGhlIHZhbHVlIFxcJ2xhYmVsXFwnLCBvciBpdCBjYW4gYmUgdXNlZCB0byBhZGQgc3BhY2luZyBiZXR3ZWVuIGEgY29tcG91bmQgbm9kZSBwYXJlbnQgYW5kIGl0cyBjaGlsZHJlbi4nKSlcbiAgZmllbGRzZXRJbmZvcy5wdXNoKG5ldyBGaWVsZHNldEluZm8oJ05vZGUnLCBub2RlRmllbGRJbmZvcykpXG4gIG5vZGVGaWVsZEluZm9zID0gW11cblxuICAvKipcbiAgICogRWRnZSBsYWJlbCBhbGlnbm1lbnQ6XG4gICAqL1xuICBub2RlRmllbGRJbmZvcy5wdXNoKG5ldyBTdHlsZUZpZWxkSW5mbygnc291cmNlLXRleHQtb2Zmc2V0JywgJ251bWJlcicsICdGb3IgdGhlIHNvdXJjZSBsYWJlbCBvZiBhbiBlZGdlLCBob3cgZmFyIGZyb20gdGhlIHNvdXJjZSBub2RlIHRoZSBsYWJlbCBzaG91bGQgYmUgcGxhY2VkLicpKVxuICBub2RlRmllbGRJbmZvcy5wdXNoKG5ldyBTdHlsZUZpZWxkSW5mbygndGFyZ2V0LXRleHQtb2Zmc2V0JywgJ251bWJlcicsICdGb3IgdGhlIHRhcmdldCBsYWJlbCBvZiBhbiBlZGdlLCBob3cgZmFyIGZyb20gdGhlIHRhcmdldCBub2RlIHRoZSBsYWJlbCBzaG91bGQgYmUgcGxhY2VkLicpKVxuICAvKipcbiAgICogTWFyZ2luczpcbiAgICovXG4gIG5vZGVGaWVsZEluZm9zLnB1c2gobmV3IFN0eWxlRmllbGRJbmZvKCd0ZXh0LW1hcmdpbi14JywgJ251bWJlcicsICdBIG1hcmdpbiB0aGF0IHNoaWZ0cyB0aGUgbGFiZWwgYWxvbmcgdGhlIHgtIGF4aXMuJykpXG4gIG5vZGVGaWVsZEluZm9zLnB1c2gobmV3IFN0eWxlRmllbGRJbmZvKCd0ZXh0LW1hcmdpbi15JywgJ251bWJlcicsICdBIG1hcmdpbiB0aGF0IHNoaWZ0cyB0aGUgbGFiZWwgYWxvbmcgdGhlIHktIGF4aXMuJykpXG4gIG5vZGVGaWVsZEluZm9zLnB1c2gobmV3IFN0eWxlRmllbGRJbmZvKCdzb3VyY2UtdGV4dC1tYXJnaW4teCcsICdudW1iZXInLCAnKEZvciB0aGUgc291cmNlIGxhYmVsIG9mIGFuIGVkZ2UuKScpKVxuICBub2RlRmllbGRJbmZvcy5wdXNoKG5ldyBTdHlsZUZpZWxkSW5mbygnc291cmNlLXRleHQtbWFyZ2luLXknLCAnbnVtYmVyJywgJyhGb3IgdGhlIHNvdXJjZSBsYWJlbCBvZiBhbiBlZGdlLiknKSlcbiAgbm9kZUZpZWxkSW5mb3MucHVzaChuZXcgU3R5bGVGaWVsZEluZm8oJ3RhcmdldC10ZXh0LW1hcmdpbi14JywgJ251bWJlcicsICcoRm9yIHRoZSB0YXJnZXQgbGFiZWwgb2YgYW4gZWRnZS4pJykpXG4gIG5vZGVGaWVsZEluZm9zLnB1c2gobmV3IFN0eWxlRmllbGRJbmZvKCd0YXJnZXQtdGV4dC1tYXJnaW4teScsICdudW1iZXInLCAnKEZvciB0aGUgdGFyZ2V0IGxhYmVsIG9mIGFuIGVkZ2UuKScpKVxuICAvKipcbiAgICogUm90YXRpbmcgdGV4dDpcbiAgICovXG4gIG5vZGVGaWVsZEluZm9zLnB1c2gobmV3IFN0eWxlRmllbGRJbmZvKCd0ZXh0LXJvdGF0aW9uJywgJ251bWJlcicsICdBIHJvdGF0aW9uIGFuZ2xlIHRoYXQgaXMgYXBwbGllZCB0byB0aGUgbGFiZWwuIEZvciBlZGdlcywgdGhlIHNwZWNpYWwgdmFsdWUgYXV0b3JvdGF0ZSBjYW4gYmUgdXNlZCB0byBhbGlnbiB0aGUgbGFiZWwgdG8gdGhlIGVkZ2UuIEZvciBub2RlcywgdGhlIGxhYmVsIGlzIHJvdGF0ZWQgYWxvbmcgaXRzIGFuY2hvciBwb2ludCBvbiB0aGUgbm9kZSwgc28gYSBsYWJlbCBtYXJnaW4gbWF5IGhlbHAgZm9yIHNvbWUgdXNlY2FzZXMuIFRoZSBzcGVjaWFsIHZhbHVlIG5vbmUgY2FuIGJlIHVzZWQgdG8gZGVub3RlIDBkZWcuIFJvdGF0aW9ucyB3b3JrcyBiZXN0IHdpdGggbGVmdC0gdG8gLSByaWdodCB0ZXh0LicpKVxuICBub2RlRmllbGRJbmZvcy5wdXNoKG5ldyBTdHlsZUZpZWxkSW5mbygnc291cmNlLXRleHQtcm90YXRpb24nLCAnbnVtYmVyJywgJyhGb3IgdGhlIHNvdXJjZSBsYWJlbCBvZiBhbiBlZGdlLiknKSlcbiAgbm9kZUZpZWxkSW5mb3MucHVzaChuZXcgU3R5bGVGaWVsZEluZm8oJ3RhcmdldC10ZXh0LXJvdGF0aW9uJywgJ251bWJlcicsICcoRm9yIHRoZSB0YXJnZXQgbGFiZWwgb2YgYW4gZWRnZS4pJykpXG4gIC8qKlxuICAgKiBPdXRsaW5lOlxuICAgKi9cbiAgbm9kZUZpZWxkSW5mb3MucHVzaChuZXcgU3R5bGVGaWVsZEluZm8oJ3RleHQtb3V0bGluZS1jb2xvcicsICdDb2xvdXInLCAnVGhlIGNvbG91ciBvZiB0aGUgb3V0bGluZSBhcm91bmQgdGhlIGVsZW1lbnTigJlzIGxhYmVsIHRleHQuJykpXG4gIG5vZGVGaWVsZEluZm9zLnB1c2gobmV3IFN0eWxlRmllbGRJbmZvKCd0ZXh0LW91dGxpbmUtb3BhY2l0eScsICdudW1iZXInLCAnVGhlIG9wYWNpdHkgb2YgdGhlIG91dGxpbmUgb24gbGFiZWwgdGV4dC4nKSlcbiAgbm9kZUZpZWxkSW5mb3MucHVzaChuZXcgU3R5bGVGaWVsZEluZm8oJ3RleHQtb3V0bGluZS13aWR0aCcsICdzdHJpbmcnLCAnVGhlIHNpemUgb2YgdGhlIG91dGxpbmUgb24gbGFiZWwgdGV4dC4nKSlcbiAgLyoqXG4gICAqIFNoYWRvdzpcbiAgICovXG4gIG5vZGVGaWVsZEluZm9zLnB1c2gobmV3IFN0eWxlRmllbGRJbmZvKCd0ZXh0LXNoYWRvdy1ibHVyJywgJ251bWJlcicsICdUaGUgc2hhZG93IGJsdXIgZGlzdGFuY2UuJykpXG4gIG5vZGVGaWVsZEluZm9zLnB1c2gobmV3IFN0eWxlRmllbGRJbmZvKCd0ZXh0LXNoYWRvdy1jb2xvcicsICdDb2xvdXInLCAnVGhlIGNvbG91ciBvZiB0aGUgc2hhZG93LicpKVxuICBub2RlRmllbGRJbmZvcy5wdXNoKG5ldyBTdHlsZUZpZWxkSW5mbygndGV4dC1zaGFkb3ctb2Zmc2V0LXgnLCAnbnVtYmVyJywgJ1RoZSB4IG9mZnNldCByZWxhdGl2ZSB0byB0aGUgdGV4dCB3aGVyZSB0aGUgc2hhZG93IHdpbGwgYmUgZGlzcGxheWVkLCBjYW4gYmUgbmVnYXRpdmUuICBJZiB5b3Ugc2V0IGJsdXIgdG8gMCwgYWRkIGFuIG9mZnNldCB0byB2aWV3IHlvdXIgc2hhZG93LicpKVxuICBub2RlRmllbGRJbmZvcy5wdXNoKG5ldyBTdHlsZUZpZWxkSW5mbygndGV4dC1zaGFkb3ctb2Zmc2V0LXknLCAnbnVtYmVyJywgJ1RoZSB5IG9mZnNldCByZWxhdGl2ZSB0byB0aGUgdGV4dCB3aGVyZSB0aGUgc2hhZG93IHdpbGwgYmUgZGlzcGxheWVkLCBjYW4gYmUgbmVnYXRpdmUuICBJZiB5b3Ugc2V0IGJsdXIgdG8gMCwgYWRkIGFuIG9mZnNldCB0byB2aWV3IHlvdXIgc2hhZG93LicpKVxuICBub2RlRmllbGRJbmZvcy5wdXNoKG5ldyBTdHlsZUZpZWxkSW5mbygndGV4dC1zaGFkb3ctb3BhY2l0eScsICdudW1iZXInLCAnVGhlIG9wYWNpdHkgb2YgdGhlIHNoYWRvdyBvbiB0aGUgdGV4dDsgdGhlIHNoYWRvdyBpcyBkaXNhYmxlZCBmb3IgMCAoZGVmYXVsdCB2YWx1ZSkuJykpXG4gIC8qKlxuICAgKiBCYWNrZ3JvdW5kOlxuICAgKi9cbiAgbm9kZUZpZWxkSW5mb3MucHVzaChuZXcgU3R5bGVGaWVsZEluZm8oJ3RleHQtYmFja2dyb3VuZC1wYWRkaW5nJywgJ3N0cmluZycsICdUaGUgcGFkZGluZyBwcm92aWRlcyB2aXN1YWwgc3BhY2luZyBiZXR3ZWVuIHRoZSB0ZXh0IGFuZCB0aGUgZWRnZSBvZiB0aGUgYmFja2dyb3VuZC4nKSlcbiAgbm9kZUZpZWxkSW5mb3MucHVzaChuZXcgU3R5bGVGaWVsZEluZm8oJ3RleHQtYmFja2dyb3VuZC1jb2xvcicsICdDb2xvdXInLCAnQSBjb2xvdXIgdG8gYXBwbHkgb24gdGhlIHRleHQgYmFja2dyb3VuZC4nKSlcbiAgbm9kZUZpZWxkSW5mb3MucHVzaChuZXcgU3R5bGVGaWVsZEluZm8oJ3RleHQtYmFja2dyb3VuZC1vcGFjaXR5JywgJ251bWJlcicsICdUaGUgb3BhY2l0eSBvZiB0aGUgbGFiZWwgYmFja2dyb3VuZDsgdGhlIGJhY2tncm91bmQgaXMgZGlzYWJsZWQgZm9yIDAgKGRlZmF1bHQgdmFsdWUpLicpKVxuICBub2RlRmllbGRJbmZvcy5wdXNoKG5ldyBTdHlsZUZpZWxkSW5mbygndGV4dC1iYWNrZ3JvdW5kLXNoYXBlJywgJ29wdGlvbnMnLFxuICAgICdUaGUgc2hhcGUgdG8gdXNlIGZvciB0aGUgbGFiZWwgYmFja2dyb3VuZC4nLCBbXG4gICAgICB7bmFtZTogJycsIGxhYmVsOiAnJ30sXG4gICAgICB7bGFiZWw6ICdyZWN0YW5nbGUnLCB2YWx1ZTogJ3JlY3RhbmdsZSd9LFxuICAgICAge2xhYmVsOiAncm91bmRyZWN0YW5nbGUnLCB2YWx1ZTogJ3JvdW5kcmVjdGFuZ2xlJ31cbiAgICBdKSlcbiAgbm9kZUZpZWxkSW5mb3MucHVzaChuZXcgU3R5bGVGaWVsZEluZm8oJ3RleHQtYm9yZGVyLW9wYWNpdHknLCAnbnVtYmVyJywgJ1RoZSB3aWR0aCBvZiB0aGUgYm9yZGVyIGFyb3VuZCB0aGUgbGFiZWw7IHRoZSBib3JkZXIgaXMgZGlzYWJsZWQgZm9yIDAgKGRlZmF1bHQgdmFsdWUpLicpKVxuICBub2RlRmllbGRJbmZvcy5wdXNoKG5ldyBTdHlsZUZpZWxkSW5mbygndGV4dC1ib3JkZXItd2lkdGgnLCAnbnVtYmVyJywgJ1RoZSB3aWR0aCBvZiB0aGUgYm9yZGVyIGFyb3VuZCB0aGUgbGFiZWwuJykpXG4gIG5vZGVGaWVsZEluZm9zLnB1c2gobmV3IFN0eWxlRmllbGRJbmZvKCd0ZXh0LWJvcmRlci1zdHlsZScsICdMaW5lU3R5bGUnLCAnVGhlIHN0eWxlIG9mIHRoZSBib3JkZXIgYXJvdW5kIHRoZSBsYWJlbC4nKSlcbiAgbm9kZUZpZWxkSW5mb3MucHVzaChuZXcgU3R5bGVGaWVsZEluZm8oJ3RleHQtYm9yZGVyLWNvbG9yJywgJ0NvbG91cicsICdUaGUgY29sb3VyIG9mIHRoZSBib3JkZXIgYXJvdW5kIHRoZSBsYWJlbC4nKSlcbiAgZmllbGRzZXRJbmZvcy5wdXNoKG5ldyBGaWVsZHNldEluZm8oJ0FkdmFuY2VkIFRleHQnLCBub2RlRmllbGRJbmZvcykpXG4gIG5vZGVGaWVsZEluZm9zID0gW11cblxuICAvKipcbiAgICogSW50ZXJhY3Rpdml0eTpcbiAgICovXG4gIG5vZGVGaWVsZEluZm9zLnB1c2gobmV3IFN0eWxlRmllbGRJbmZvKCdtaW4tem9vbWVkLWZvbnQtc2l6ZScsICdudW1iZXInLCAnSWYgem9vbWluZyBtYWtlcyB0aGUgZWZmZWN0aXZlIGZvbnQgc2l6ZSBvZiB0aGUgbGFiZWwgc21hbGxlciB0aGFuIHRoaXMsIHRoZW4gbm8gbGFiZWwgaXMgc2hvd24uTm90ZSB0aGF0IGJlY2F1c2Ugb2YgcGVyZm9ybWFuY2Ugb3B0aW1pc2F0aW9ucywgdGhlIGxhYmVsIG1heSBiZSBzaG93biBhdCBmb250IHNpemVzIHNsaWdodGx5IHNtYWxsZXIgdGhhbiB0aGlzIHZhbHVlLiBUaGlzIGVmZmVjdCBpcyBtb3JlIHByb25vdW5jZWQgYXQgbGFyZ2VyIHNjcmVlbiBwaXhlbCByYXRpb3MuIEhvd2V2ZXIsIGl0IGlzIGd1YXJhbnRlZWQgdGhhdCB0aGUgbGFiZWwgd2lsbCBiZSBzaG93biBhdCBzaXplcyBlcXVhbCB0byBvciBncmVhdGVyIHRoYW4gdGhlIHZhbHVlIHNwZWNpZmllZC4nKSlcbiAgbm9kZUZpZWxkSW5mb3MucHVzaChuZXcgU3R5bGVGaWVsZEluZm8oJ3RleHQtZXZlbnRzJywgJ29wdGlvbnMnLFxuICAgICdXaGV0aGVyIGV2ZW50cyBzaG91bGQgb2NjdXIgb24gYW4gZWxlbWVudCBpZiB0aGUgbGFiZWwgcmVjZWl2ZXMgYW4gZXZlbnQuIFlvdSBtYXkgd2FudCBhIHN0eWxlIGFwcGxpZWQgdG8gdGhlIHRleHQgb25hY3RpdmUgc28geW91IGtub3cgdGhlIHRleHQgaXMgYWN0aXZhdGFibGUuJywgW1xuICAgICAge2xhYmVsOiAneWVzJywgdmFsdWU6ICd5ZXMnfSxcbiAgICAgIHtsYWJlbDogJ25vJywgdmFsdWU6ICdubyd9XG4gICAgXSkpXG4gIGZpZWxkc2V0SW5mb3MucHVzaChuZXcgRmllbGRzZXRJbmZvKCdJbnRlcmFjdGl2aXR5Jywgbm9kZUZpZWxkSW5mb3MpKVxuICByZXR1cm4gZmllbGRzZXRJbmZvc1xufVxuXG4vKipcbiAqIERlZmF1bHRzIHRvIGEgYmxhbmsgbm9kZVxuICovXG5leHBvcnQgY2xhc3MgU3R5bGVzaGVldEltcGwgaW1wbGVtZW50cyBTdHlsZXNoZWV0U3R5bGUge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgc2VsZWN0b3I6IHN0cmluZyA9ICdub2RlJyxcbiAgICBwdWJsaWMgc3R5bGU6IGN5dG9zY2FwZS5Dc3MuTm9kZSB8IGN5dG9zY2FwZS5Dc3MuRWRnZSB8IGN5dG9zY2FwZS5Dc3MuQ29yZSA9IHt9XG4gICkge1xuICB9XG59XG4iXX0=