πŸ“„ File detail

components/permissions/PowerShellPermissionRequest/PowerShellPermissionRequest.tsx

🧩 .tsxπŸ“ 235 linesπŸ’Ύ 38,696 bytesπŸ“ text
← Back to All Files

🎯 Use case

This file lives under β€œcomponents/”, which covers shared React UI pieces. On the API surface it exposes PowerShellPermissionRequest β€” mainly types, interfaces, or factory objects. Dependencies touch React UI. It composes internal code from ink, keybindings, services, tools, and utils (relative imports).

Generated from folder role, exports, dependency roots, and inline comments β€” not hand-reviewed for every path.

🧠 Inline summary

import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { Box, Text, useTheme } from '../../../ink.js'; import { useKeybinding } from '../../../keybindings/useKeybinding.js'; import { getFeatureValue_CACHED_MAY_BE_STALE } from '../../../services/analytics/growthbook.js'; import { type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, logEvent } from '../.

πŸ“€ Exports (heuristic)

  • PowerShellPermissionRequest

πŸ“š External import roots

Package roots from from "…" (relative paths omitted).

  • react

πŸ–₯️ Source preview

import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { Box, Text, useTheme } from '../../../ink.js';
import { useKeybinding } from '../../../keybindings/useKeybinding.js';
import { getFeatureValue_CACHED_MAY_BE_STALE } from '../../../services/analytics/growthbook.js';
import { type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, logEvent } from '../../../services/analytics/index.js';
import { sanitizeToolNameForAnalytics } from '../../../services/analytics/metadata.js';
import { getDestructiveCommandWarning } from '../../../tools/PowerShellTool/destructiveCommandWarning.js';
import { PowerShellTool } from '../../../tools/PowerShellTool/PowerShellTool.js';
import { isAllowlistedCommand } from '../../../tools/PowerShellTool/readOnlyValidation.js';
import type { PermissionUpdate } from '../../../utils/permissions/PermissionUpdateSchema.js';
import { getCompoundCommandPrefixesStatic } from '../../../utils/powershell/staticPrefix.js';
import { Select } from '../../CustomSelect/select.js';
import { type UnaryEvent, usePermissionRequestLogging } from '../hooks.js';
import { PermissionDecisionDebugInfo } from '../PermissionDecisionDebugInfo.js';
import { PermissionDialog } from '../PermissionDialog.js';
import { PermissionExplainerContent, usePermissionExplainerUI } from '../PermissionExplanation.js';
import type { PermissionRequestProps } from '../PermissionRequest.js';
import { PermissionRuleExplanation } from '../PermissionRuleExplanation.js';
import { useShellPermissionFeedback } from '../useShellPermissionFeedback.js';
import { logUnaryPermissionEvent } from '../utils.js';
import { powershellToolUseOptions } from './powershellToolUseOptions.js';
export function PowerShellPermissionRequest(props: PermissionRequestProps): React.ReactNode {
  const {
    toolUseConfirm,
    toolUseContext,
    onDone,
    onReject,
    workerBadge
  } = props;
  const {
    command,
    description
  } = PowerShellTool.inputSchema.parse(toolUseConfirm.input);
  const [theme] = useTheme();
  const explainerState = usePermissionExplainerUI({
    toolName: toolUseConfirm.tool.name,
    toolInput: toolUseConfirm.input,
    toolDescription: toolUseConfirm.description,
    messages: toolUseContext.messages
  });
  const {
    yesInputMode,
    noInputMode,
    yesFeedbackModeEntered,
    noFeedbackModeEntered,
    acceptFeedback,
    rejectFeedback,
    setAcceptFeedback,
    setRejectFeedback,
    focusedOption,
    handleInputModeToggle,
    handleReject,
    handleFocus
  } = useShellPermissionFeedback({
    toolUseConfirm,
    onDone,
    onReject,
    explainerVisible: explainerState.visible
  });
  const destructiveWarning = getFeatureValue_CACHED_MAY_BE_STALE('tengu_destructive_command_warning', false) ? getDestructiveCommandWarning(command) : null;
  const [showPermissionDebug, setShowPermissionDebug] = useState(false);

  // Editable prefix β€” compute static prefix locally (no LLM call).
  // Initialize synchronously to the raw command for single-line commands so
  // the editable input renders immediately, then refine to the extracted prefix
  // once the AST parser resolves. Multiline commands (`# comment\n...`,
  // foreach loops) get undefined β†’ powershellToolUseOptions:64 hides the
  // "don't ask again" option β€” those literals are one-time-use (settings
  // corpus shows 14 multiline rules, zero match twice). For compound commands,
  // computes a prefix per subcommand, excluding subcommands that are already
  // auto-allowed (read-only).
  const [editablePrefix, setEditablePrefix] = useState<string | undefined>(command.includes('\n') ? undefined : command);
  const hasUserEditedPrefix = useRef(false);
  useEffect(() => {
    let cancelled = false;
    // Filter receives ParsedCommandElement β€” isAllowlistedCommand works from
    // element.name/nameType/args directly. isReadOnlyCommand(text) would need
    // to reparse (pwsh.exe spawn per subcommand) and returns false without the
    // full parsed AST, making the filter a no-op.
    getCompoundCommandPrefixesStatic(command, element => isAllowlistedCommand(element, element.text)).then(prefixes => {
      if (cancelled || hasUserEditedPrefix.current) return;
      if (prefixes.length > 0) {
        setEditablePrefix(`${prefixes[0]}:*`);
      }
    }).catch(() => {});
    return () => {
      cancelled = true;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [command]);
  const onEditablePrefixChange = useCallback((value: string) => {
    hasUserEditedPrefix.current = true;
    setEditablePrefix(value);
  }, []);
  const unaryEvent = useMemo<UnaryEvent>(() => ({
    completion_type: 'tool_use_single',
    language_name: 'none'
  }), []);
  usePermissionRequestLogging(toolUseConfirm, unaryEvent);
  const options = useMemo(() => powershellToolUseOptions({
    suggestions: toolUseConfirm.permissionResult.behavior === 'ask' ? toolUseConfirm.permissionResult.suggestions : undefined,
    onRejectFeedbackChange: setRejectFeedback,
    onAcceptFeedbackChange: setAcceptFeedback,
    yesInputMode,
    noInputMode,
    editablePrefix,
    onEditablePrefixChange
  }), [toolUseConfirm, yesInputMode, noInputMode, editablePrefix, onEditablePrefixChange]);

  // Toggle permission debug info with keybinding
  const handleToggleDebug = useCallback(() => {
    setShowPermissionDebug(prev => !prev);
  }, []);
  useKeybinding('permission:toggleDebug', handleToggleDebug, {
    context: 'Confirmation'
  });
  function onSelect(value: string) {
    // Map options to numeric values for analytics (strings not allowed in logEvent)
    const optionIndex: Record<string, number> = {
      yes: 1,
      'yes-apply-suggestions': 2,
      'yes-prefix-edited': 2,
      no: 3
    };
    logEvent('tengu_permission_request_option_selected', {
      option_index: optionIndex[value],
      explainer_visible: explainerState.visible
    });
    const toolNameForAnalytics = sanitizeToolNameForAnalytics(toolUseConfirm.tool.name) as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS;
    if (value === 'yes-prefix-edited') {
      const trimmedPrefix = (editablePrefix ?? '').trim();
      logUnaryPermissionEvent('tool_use_single', toolUseConfirm, 'accept');
      if (!trimmedPrefix) {
        toolUseConfirm.onAllow(toolUseConfirm.input, []);
      } else {
        const prefixUpdates: PermissionUpdate[] = [{
          type: 'addRules',
          rules: [{
            toolName: PowerShellTool.name,
            ruleContent: trimmedPrefix
          }],
          behavior: 'allow',
          destination: 'localSettings'
        }];
        toolUseConfirm.onAllow(toolUseConfirm.input, prefixUpdates);
      }
      onDone();
      return;
    }
    switch (value) {
      case 'yes':
        {
          const trimmedFeedback = acceptFeedback.trim();
          logUnaryPermissionEvent('tool_use_single', toolUseConfirm, 'accept');
          // Log accept submission with feedback context
          logEvent('tengu_accept_submitted', {
            toolName: toolNameForAnalytics,
            isMcp: toolUseConfirm.tool.isMcp ?? false,
            has_instructions: !!trimmedFeedback,
            instructions_length: trimmedFeedback.length,
            entered_feedback_mode: yesFeedbackModeEntered
          });
          toolUseConfirm.onAllow(toolUseConfirm.input, [], trimmedFeedback || undefined);
          onDone();
          break;
        }
      case 'yes-apply-suggestions':
        {
          logUnaryPermissionEvent('tool_use_single', toolUseConfirm, 'accept');
          // Extract suggestions if present (works for both 'ask' and 'passthrough' behaviors)
          const permissionUpdates = 'suggestions' in toolUseConfirm.permissionResult ? toolUseConfirm.permissionResult.suggestions || [] : [];
          toolUseConfirm.onAllow(toolUseConfirm.input, permissionUpdates);
          onDone();
          break;
        }
      case 'no':
        {
          const trimmedFeedback = rejectFeedback.trim();

          // Log reject submission with feedback context
          logEvent('tengu_reject_submitted', {
            toolName: toolNameForAnalytics,
            isMcp: toolUseConfirm.tool.isMcp ?? false,
            has_instructions: !!trimmedFeedback,
            instructions_length: trimmedFeedback.length,
            entered_feedback_mode: noFeedbackModeEntered
          });

          // Process rejection (with or without feedback)
          handleReject(trimmedFeedback || undefined);
          break;
        }
    }
  }
  return <PermissionDialog workerBadge={workerBadge} title="PowerShell command">
      <Box flexDirection="column" paddingX={2} paddingY={1}>
        <Text dimColor={explainerState.visible}>
          {PowerShellTool.renderToolUseMessage({
          command,
          description
        }, {
          theme,
          verbose: true
        } // always show the full command
        )}
        </Text>
        {!explainerState.visible && <Text dimColor>{toolUseConfirm.description}</Text>}
        <PermissionExplainerContent visible={explainerState.visible} promise={explainerState.promise} />
      </Box>
      {showPermissionDebug ? <>
          <PermissionDecisionDebugInfo permissionResult={toolUseConfirm.permissionResult} toolName="PowerShell" />
          {toolUseContext.options.debug && <Box justifyContent="flex-end" marginTop={1}>
              <Text dimColor>Ctrl-D to hide debug info</Text>
            </Box>}
        </> : <>
          <Box flexDirection="column">
            <PermissionRuleExplanation permissionResult={toolUseConfirm.permissionResult} toolType="command" />
            {destructiveWarning && <Box marginBottom={1}>
                <Text color="warning">{destructiveWarning}</Text>
              </Box>}
            <Text>Do you want to proceed?</Text>
            <Select options={options} inlineDescriptions onChange={onSelect} onCancel={() => handleReject()} onFocus={handleFocus} onInputModeToggle={handleInputModeToggle} />
          </Box>
          <Box justifyContent="space-between" marginTop={1}>
            <Text dimColor>
              Esc to cancel
              {(focusedOption === 'yes' && !yesInputMode || focusedOption === 'no' && !noInputMode) && ' Β· Tab to amend'}
              {explainerState.enabled && ` Β· ctrl+e to ${explainerState.visible ? 'hide' : 'explain'}`}
            </Text>
            {toolUseContext.options.debug && <Text dimColor>Ctrl+d to show debug info</Text>}
          </Box>
        </>}
    </PermissionDialog>;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSZWFjdCIsInVzZUNhbGxiYWNrIiwidXNlRWZmZWN0IiwidXNlTWVtbyIsInVzZVJlZiIsInVzZVN0YXRlIiwiQm94IiwiVGV4dCIsInVzZVRoZW1lIiwidXNlS2V5YmluZGluZyIsImdldEZlYXR1cmVWYWx1ZV9DQUNIRURfTUFZX0JFX1NUQUxFIiwiQW5hbHl0aWNzTWV0YWRhdGFfSV9WRVJJRklFRF9USElTX0lTX05PVF9DT0RFX09SX0ZJTEVQQVRIUyIsImxvZ0V2ZW50Iiwic2FuaXRpemVUb29sTmFtZUZvckFuYWx5dGljcyIsImdldERlc3RydWN0aXZlQ29tbWFuZFdhcm5pbmciLCJQb3dlclNoZWxsVG9vbCIsImlzQWxsb3dsaXN0ZWRDb21tYW5kIiwiUGVybWlzc2lvblVwZGF0ZSIsImdldENvbXBvdW5kQ29tbWFuZFByZWZpeGVzU3RhdGljIiwiU2VsZWN0IiwiVW5hcnlFdmVudCIsInVzZVBlcm1pc3Npb25SZXF1ZXN0TG9nZ2luZyIsIlBlcm1pc3Npb25EZWNpc2lvbkRlYnVnSW5mbyIsIlBlcm1pc3Npb25EaWFsb2ciLCJQZXJtaXNzaW9uRXhwbGFpbmVyQ29udGVudCIsInVzZVBlcm1pc3Npb25FeHBsYWluZXJVSSIsIlBlcm1pc3Npb25SZXF1ZXN0UHJvcHMiLCJQZXJtaXNzaW9uUnVsZUV4cGxhbmF0aW9uIiwidXNlU2hlbGxQZXJtaXNzaW9uRmVlZGJhY2siLCJsb2dVbmFyeVBlcm1pc3Npb25FdmVudCIsInBvd2Vyc2hlbGxUb29sVXNlT3B0aW9ucyIsIlBvd2VyU2hlbGxQZXJtaXNzaW9uUmVxdWVzdCIsInByb3BzIiwiUmVhY3ROb2RlIiwidG9vbFVzZUNvbmZpcm0iLCJ0b29sVXNlQ29udGV4dCIsIm9uRG9uZSIsIm9uUmVqZWN0Iiwid29ya2VyQmFkZ2UiLCJjb21tYW5kIiwiZGVzY3JpcHRpb24iLCJpbnB1dFNjaGVtYSIsInBhcnNlIiwiaW5wdXQiLCJ0aGVtZSIsImV4cGxhaW5lclN0YXRlIiwidG9vbE5hbWUiLCJ0b29sIiwibmFtZSIsInRvb2xJbnB1dCIsInRvb2xEZXNjcmlwdGlvbiIsIm1lc3NhZ2VzIiwieWVzSW5wdXRNb2RlIiwibm9JbnB1dE1vZGUiLCJ5ZXNGZWVkYmFja01vZGVFbnRlcmVkIiwibm9GZWVkYmFja01vZGVFbnRlcmVkIiwiYWNjZXB0RmVlZGJhY2siLCJyZWplY3RGZWVkYmFjayIsInNldEFjY2VwdEZlZWRiYWNrIiwic2V0UmVqZWN0RmVlZGJhY2siLCJmb2N1c2VkT3B0aW9uIiwiaGFuZGxlSW5wdXRNb2RlVG9nZ2xlIiwiaGFuZGxlUmVqZWN0IiwiaGFuZGxlRm9jdXMiLCJleHBsYWluZXJWaXNpYmxlIiwidmlzaWJsZSIsImRlc3RydWN0aXZlV2FybmluZyIsInNob3dQZXJtaXNzaW9uRGVidWciLCJzZXRTaG93UGVybWlzc2lvbkRlYnVnIiwiZWRpdGFibGVQcmVmaXgiLCJzZXRFZGl0YWJsZVByZWZpeCIsImluY2x1ZGVzIiwidW5kZWZpbmVkIiwiaGFzVXNlckVkaXRlZFByZWZpeCIsImNhbmNlbGxlZCIsImVsZW1lbnQiLCJ0ZXh0IiwidGhlbiIsInByZWZpeGVzIiwiY3VycmVudCIsImxlbmd0aCIsImNhdGNoIiwib25FZGl0YWJsZVByZWZpeENoYW5nZSIsInZhbHVlIiwidW5hcnlFdmVudCIsImNvbXBsZXRpb25fdHlwZSIsImxhbmd1YWdlX25hbWUiLCJvcHRpb25zIiwic3VnZ2VzdGlvbnMiLCJwZXJtaXNzaW9uUmVzdWx0IiwiYmVoYXZpb3IiLCJvblJlamVjdEZlZWRiYWNrQ2hhbmdlIiwib25BY2NlcHRGZWVkYmFja0NoYW5nZSIsImhhbmRsZVRvZ2dsZURlYnVnIiwicHJldiIsImNvbnRleHQiLCJvblNlbGVjdCIsIm9wdGlvbkluZGV4IiwiUmVjb3JkIiwieWVzIiwibm8iLCJvcHRpb25faW5kZXgiLCJleHBsYWluZXJfdmlzaWJsZSIsInRvb2xOYW1lRm9yQW5hbHl0aWNzIiwidHJpbW1lZFByZWZpeCIsInRyaW0iLCJvbkFsbG93IiwicHJlZml4VXBkYXRlcyIsInR5cGUiLCJydWxlcyIsInJ1bGVDb250ZW50IiwiZGVzdGluYXRpb24iLCJ0cmltbWVkRmVlZGJhY2siLCJpc01jcCIsImhhc19pbnN0cnVjdGlvbnMiLCJpbnN0cnVjdGlvbnNfbGVuZ3RoIiwiZW50ZXJlZF9mZWVkYmFja19tb2RlIiwicGVybWlzc2lvblVwZGF0ZXMiLCJyZW5kZXJUb29sVXNlTWVzc2FnZSIsInZlcmJvc2UiLCJwcm9taXNlIiwiZGVidWciLCJlbmFibGVkIl0sInNvdXJjZXMiOlsiUG93ZXJTaGVsbFBlcm1pc3Npb25SZXF1ZXN0LnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUmVhY3QsIHsgdXNlQ2FsbGJhY2ssIHVzZUVmZmVjdCwgdXNlTWVtbywgdXNlUmVmLCB1c2VTdGF0ZSB9IGZyb20gJ3JlYWN0J1xuaW1wb3J0IHsgQm94LCBUZXh0LCB1c2VUaGVtZSB9IGZyb20gJy4uLy4uLy4uL2luay5qcydcbmltcG9ydCB7IHVzZUtleWJpbmRpbmcgfSBmcm9tICcuLi8uLi8uLi9rZXliaW5kaW5ncy91c2VLZXliaW5kaW5nLmpzJ1xuaW1wb3J0IHsgZ2V0RmVhdHVyZVZhbHVlX0NBQ0hFRF9NQVlfQkVfU1RBTEUgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9hbmFseXRpY3MvZ3Jvd3RoYm9vay5qcydcbmltcG9ydCB7XG4gIHR5cGUgQW5hbHl0aWNzTWV0YWRhdGFfSV9WRVJJRklFRF9USElTX0lTX05PVF9DT0RFX09SX0ZJTEVQQVRIUyxcbiAgbG9nRXZlbnQsXG59IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2FuYWx5dGljcy9pbmRleC5qcydcbmltcG9ydCB7IHNhbml0aXplVG9vbE5hbWVGb3JBbmFseXRpY3MgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9hbmFseXRpY3MvbWV0YWRhdGEuanMnXG5pbXBvcnQgeyBnZXREZXN0cnVjdGl2ZUNvbW1hbmRXYXJuaW5nIH0gZnJvbSAnLi4vLi4vLi4vdG9vbHMvUG93ZXJTaGVsbFRvb2wvZGVzdHJ1Y3RpdmVDb21tYW5kV2FybmluZy5qcydcbmltcG9ydCB7IFBvd2VyU2hlbGxUb29sIH0gZnJvbSAnLi4vLi4vLi4vdG9vbHMvUG93ZXJTaGVsbFRvb2wvUG93ZXJTaGVsbFRvb2wuanMnXG5pbXBvcnQgeyBpc0FsbG93bGlzdGVkQ29tbWFuZCB9IGZyb20gJy4uLy4uLy4uL3Rvb2xzL1Bvd2VyU2hlbGxUb29sL3JlYWRPbmx5VmFsaWRhdGlvbi5qcydcbmltcG9ydCB0eXBlIHsgUGVybWlzc2lvblVwZGF0ZSB9IGZyb20gJy4uLy4uLy4uL3V0aWxzL3Blcm1pc3Npb25zL1Blcm1pc3Npb25VcGRhdGVTY2hlbWEuanMnXG5pbXBvcnQgeyBnZXRDb21wb3VuZENvbW1hbmRQcmVmaXhlc1N0YXRpYyB9IGZyb20gJy4uLy4uLy4uL3V0aWxzL3Bvd2Vyc2hlbGwvc3RhdGljUHJlZml4LmpzJ1xuaW1wb3J0IHsgU2VsZWN0IH0gZnJvbSAnLi4vLi4vQ3VzdG9tU2VsZWN0L3NlbGVjdC5qcydcbmltcG9ydCB7IHR5cGUgVW5hcnlFdmVudCwgdXNlUGVybWlzc2lvblJlcXVlc3RMb2dnaW5nIH0gZnJvbSAnLi4vaG9va3MuanMnXG5pbXBvcnQgeyBQZXJtaXNzaW9uRGVjaXNpb25EZWJ1Z0luZm8gfSBmcm9tICcuLi9QZXJtaXNzaW9uRGVjaXNpb25EZWJ1Z0luZm8uanMnXG5pbXBvcnQgeyBQZXJtaXNzaW9uRGlhbG9nIH0gZnJvbSAnLi4vUGVybWlzc2lvbkRpYWxvZy5qcydcbmltcG9ydCB7XG4gIFBlcm1pc3Npb25FeHBsYWluZXJDb250ZW50LFxuICB1c2VQZXJtaXNzaW9uRXhwbGFpbmVyVUksXG59IGZyb20gJy4uL1Blcm1pc3Npb25FeHBsYW5hdGlvbi5qcydcbmltcG9ydCB0eXBlIHsgUGVybWlzc2lvblJlcXVlc3RQcm9wcyB9IGZyb20gJy4uL1Blcm1pc3Npb25SZXF1ZXN0LmpzJ1xuaW1wb3J0IHsgUGVybWlzc2lvblJ1bGVFeHBsYW5hdGlvbiB9IGZyb20gJy4uL1Blcm1pc3Npb25SdWxlRXhwbGFuYXRpb24uanMnXG5pbXBvcnQgeyB1c2VTaGVsbFBlcm1pc3Npb25GZWVkYmFjayB9IGZyb20gJy4uL3VzZVNoZWxsUGVybWlzc2lvbkZlZWRiYWNrLmpzJ1xuaW1wb3J0IHsgbG9nVW5hcnlQZXJtaXNzaW9uRXZlbnQgfSBmcm9tICcuLi91dGlscy5qcydcbmltcG9ydCB7IHBvd2Vyc2hlbGxUb29sVXNlT3B0aW9ucyB9IGZyb20gJy4vcG93ZXJzaGVsbFRvb2xVc2VPcHRpb25zLmpzJ1xuXG5leHBvcnQgZnVuY3Rpb24gUG93ZXJTaGVsbFBlcm1pc3Npb25SZXF1ZXN0KFxuICBwcm9wczogUGVybWlzc2lvblJlcXVlc3RQcm9wcyxcbik6IFJlYWN0LlJlYWN0Tm9kZSB7XG4gIGNvbnN0IHsgdG9vbFVzZUNvbmZpcm0sIHRvb2xVc2VDb250ZXh0LCBvbkRvbmUsIG9uUmVqZWN0LCB3b3JrZXJCYWRnZSB9ID1cbiAgICBwcm9wc1xuXG4gIGNvbnN0IHsgY29tbWFuZCwgZGVzY3JpcHRpb24gfSA9IFBvd2VyU2hlbGxUb29sLmlucHV0U2NoZW1hLnBhcnNlKFxuICAgIHRvb2xVc2VDb25maXJtLmlucHV0LFxuICApXG5cbiAgY29uc3QgW3RoZW1lXSA9IHVzZVRoZW1lKClcbiAgY29uc3QgZXhwbGFpbmVyU3RhdGUgPSB1c2VQZXJtaXNzaW9uRXhwbGFpbmVyVUkoe1xuICAgIHRvb2xOYW1lOiB0b29sVXNlQ29uZmlybS50b29sLm5hbWUsXG4gICAgdG9vbElucHV0OiB0b29sVXNlQ29uZmlybS5pbnB1dCxcbiAgICB0b29sRGVzY3JpcHRpb246IHRvb2xVc2VDb25maXJtLmRlc2NyaXB0aW9uLFxuICAgIG1lc3NhZ2VzOiB0b29sVXNlQ29udGV4dC5tZXNzYWdlcyxcbiAgfSlcbiAgY29uc3Qge1xuICAgIHllc0lucHV0TW9kZSxcbiAgICBub0lucHV0TW9kZSxcbiAgICB5ZXNGZWVkYmFja01vZGVFbnRlcmVkLFxuICAgIG5vRmVlZGJhY2tNb2RlRW50ZXJlZCxcbiAgICBhY2NlcHRGZWVkYmFjayxcbiAgICByZWplY3RGZWVkYmFjayxcbiAgICBzZXRBY2NlcHRGZWVkYmFjayxcbiAgICBzZXRSZWplY3RGZWVkYmFjayxcbiAgICBmb2N1c2VkT3B0aW9uLFxuICAgIGhhbmRsZUlucHV0TW9kZVRvZ2dsZSxcbiAgICBoYW5kbGVSZWplY3QsXG4gICAgaGFuZGxlRm9jdXMsXG4gIH0gPSB1c2VTaGVsbFBlcm1pc3Npb25GZWVkYmFjayh7XG4gICAgdG9vbFVzZUNvbmZpcm0sXG4gICAgb25Eb25lLFxuICAgIG9uUmVqZWN0LFxuICAgIGV4cGxhaW5lclZpc2libGU6IGV4cGxhaW5lclN0YXRlLnZpc2libGUsXG4gIH0pXG4gIGNvbnN0IGRlc3RydWN0aXZlV2FybmluZyA9IGdldEZlYXR1cmVWYWx1ZV9DQUNIRURfTUFZX0JFX1NUQUxFKFxuICAgICd0ZW5ndV9kZXN0cnVjdGl2ZV9jb21tYW5kX3dhcm5pbmcnLFxuICAgIGZhbHNlLFxuICApXG4gICAgPyBnZXREZXN0cnVjdGl2ZUNvbW1hbmRXYXJuaW5nKGNvbW1hbmQpXG4gICAgOiBudWxsXG5cbiAgY29uc3QgW3Nob3dQZXJtaXNzaW9uRGVidWcsIHNldFNob3dQZXJtaXNzaW9uRGVidWddID0gdXNlU3RhdGUoZmFsc2UpXG5cbiAgLy8gRWRpdGFibGUgcHJlZml4IOKAlCBjb21wdXRlIHN0YXRpYyBwcmVmaXggbG9jYWxseSAobm8gTExNIGNhbGwpLlxuICAvLyBJbml0aWFsaXplIHN5bmNocm9ub3VzbHkgdG8gdGhlIHJhdyBjb21tYW5kIGZvciBzaW5nbGUtbGluZSBjb21tYW5kcyBzb1xuICAvLyB0aGUgZWRpdGFibGUgaW5wdXQgcmVuZGVycyBpbW1lZGlhdGVseSwgdGhlbiByZWZpbmUgdG8gdGhlIGV4dHJhY3RlZCBwcmVmaXhcbiAgLy8gb25jZSB0aGUgQVNUIHBhcnNlciByZXNvbHZlcy4gTXVsdGlsaW5lIGNvbW1hbmRzIChgIyBjb21tZW50XFxuLi4uYCxcbiAgLy8gZm9yZWFjaCBsb29wcykgZ2V0IHVuZGVmaW5lZCDihpIgcG93ZXJzaGVsbFRvb2xVc2VPcHRpb25zOjY0IGhpZGVzIHRoZVxuICAvLyBcImRvbid0IGFzayBhZ2FpblwiIG9wdGlvbiDigJQgdGhvc2UgbGl0ZXJhbHMgYXJlIG9uZS10aW1lLXVzZSAoc2V0dGluZ3NcbiAgLy8gY29ycHVzIHNob3dzIDE0IG11bHRpbGluZSBydWxlcywgemVybyBtYXRjaCB0d2ljZSkuIEZvciBjb21wb3VuZCBjb21tYW5kcyxcbiAgLy8gY29tcHV0ZXMgYSBwcmVmaXggcGVyIHN1YmNvbW1hbmQsIGV4Y2x1ZGluZyBzdWJjb21tYW5kcyB0aGF0IGFyZSBhbHJlYWR5XG4gIC8vIGF1dG8tYWxsb3dlZCAocmVhZC1vbmx5KS5cbiAgY29uc3QgW2VkaXRhYmxlUHJlZml4LCBzZXRFZGl0YWJsZVByZWZpeF0gPSB1c2VTdGF0ZTxzdHJpbmcgfCB1bmRlZmluZWQ+KFxuICAgIGNvbW1hbmQuaW5jbHVkZXMoJ1xcbicpID8gdW5kZWZpbmVkIDogY29tbWFuZCxcbiAgKVxuICBjb25zdCBoYXNVc2VyRWRpdGVkUHJlZml4ID0gdXNlUmVmKGZhbHNlKVxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGxldCBjYW5jZWxsZWQgPSBmYWxzZVxuICAgIC8vIEZpbHRlciByZWNlaXZlcyBQYXJzZWRDb21tYW5kRWxlbWVudCDigJQgaXNBbGxvd2xpc3RlZENvbW1hbmQgd29ya3MgZnJvbVxuICAgIC8vIGVsZW1lbnQubmFtZS9uYW1lVHlwZS9hcmdzIGRpcmVjdGx5LiBpc1JlYWRPbmx5Q29tbWFuZCh0ZXh0KSB3b3VsZCBuZWVkXG4gICAgLy8gdG8gcmVwYXJzZSAocHdzaC5leGUgc3Bhd24gcGVyIHN1YmNvbW1hbmQpIGFuZCByZXR1cm5zIGZhbHNlIHdpdGhvdXQgdGhlXG4gICAgLy8gZnVsbCBwYXJzZWQgQVNULCBtYWtpbmcgdGhlIGZpbHRlciBhIG5vLW9wLlxuICAgIGdldENvbXBvdW5kQ29tbWFuZFByZWZpeGVzU3RhdGljKGNvbW1hbmQsIGVsZW1lbnQgPT5cbiAgICAgIGlzQWxsb3dsaXN0ZWRDb21tYW5kKGVsZW1lbnQsIGVsZW1lbnQudGV4dCksXG4gICAgKVxuICAgICAgLnRoZW4ocHJlZml4ZXMgPT4ge1xuICAgICAgICBpZiAoY2FuY2VsbGVkIHx8IGhhc1VzZXJFZGl0ZWRQcmVmaXguY3VycmVudCkgcmV0dXJuXG4gICAgICAgIGlmIChwcmVmaXhlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgc2V0RWRpdGFibGVQcmVmaXgoYCR7cHJlZml4ZXNbMF19OipgKVxuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgLmNhdGNoKCgpID0+IHt9KVxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBjYW5jZWxsZWQgPSB0cnVlXG4gICAgfVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1ob29rcy9leGhhdXN0aXZlLWRlcHNcbiAgfSwgW2NvbW1hbmRdKVxuXG4gIGNvbnN0IG9uRWRpdGFibGVQcmVmaXhDaGFuZ2UgPSB1c2VDYWxsYmFjaygodmFsdWU6IHN0cmluZykgPT4ge1xuICAgIGhhc1VzZXJFZGl0ZWRQcmVmaXguY3VycmVudCA9IHRydWVcbiAgICBzZXRFZGl0YWJsZVByZWZpeCh2YWx1ZSlcbiAgfSwgW10pXG5cbiAgY29uc3QgdW5hcnlFdmVudCA9IHVzZU1lbW88VW5hcnlFdmVudD4oXG4gICAgKCkgPT4gKHsgY29tcGxldGlvbl90eXBlOiAndG9vbF91c2Vfc2luZ2xlJywgbGFuZ3VhZ2VfbmFtZTogJ25vbmUnIH0pLFxuICAgIFtdLFxuICApXG5cbiAgdXNlUGVybWlzc2lvblJlcXVlc3RMb2dnaW5nKHRvb2xVc2VDb25maXJtLCB1bmFyeUV2ZW50KVxuXG4gIGNvbnN0IG9wdGlvbnMgPSB1c2VNZW1vKFxuICAgICgpID0+XG4gICAgICBwb3dlcnNoZWxsVG9vbFVzZU9wdGlvbnMoe1xuICAgICAgICBzdWdnZXN0aW9uczpcbiAgICAgICAgICB0b29sVXNlQ29uZmlybS5wZXJtaXNzaW9uUmVzdWx0LmJlaGF2aW9yID09PSAnYXNrJ1xuICAgICAgICAgICAgPyB0b29sVXNlQ29uZmlybS5wZXJtaXNzaW9uUmVzdWx0LnN1Z2dlc3Rpb25zXG4gICAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgICAgb25SZWplY3RGZWVkYmFja0NoYW5nZTogc2V0UmVqZWN0RmVlZGJhY2ssXG4gICAgICAgIG9uQWNjZXB0RmVlZGJhY2tDaGFuZ2U6IHNldEFjY2VwdEZlZWRiYWNrLFxuICAgICAgICB5ZXNJbnB1dE1vZGUsXG4gICAgICAgIG5vSW5wdXRNb2RlLFxuICAgICAgICBlZGl0YWJsZVByZWZpeCxcbiAgICAgICAgb25FZGl0YWJsZVByZWZpeENoYW5nZSxcbiAgICAgIH0pLFxuICAgIFtcbiAgICAgIHRvb2xVc2VDb25maXJtLFxuICAgICAgeWVzSW5wdXRNb2RlLFxuICAgICAgbm9JbnB1dE1vZGUsXG4gICAgICBlZGl0YWJsZVByZWZpeCxcbiAgICAgIG9uRWRpdGFibGVQcmVmaXhDaGFuZ2UsXG4gICAgXSxcbiAgKVxuXG4gIC8vIFRvZ2dsZSBwZXJtaXNzaW9uIGRlYnVnIGluZm8gd2l0aCBrZXliaW5kaW5nXG4gIGNvbnN0IGhhbmRsZVRvZ2dsZURlYnVnID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIHNldFNob3dQZXJtaXNzaW9uRGVidWcocHJldiA9PiAhcHJldilcbiAgfSwgW10pXG4gIHVzZUtleWJpbmRpbmcoJ3Blcm1pc3Npb246dG9nZ2xlRGVidWcnLCBoYW5kbGVUb2dnbGVEZWJ1Zywge1xuICAgIGNvbnRleHQ6ICdDb25maXJtYXRpb24nLFxuICB9KVxuXG4gIGZ1bmN0aW9uIG9uU2VsZWN0KHZhbHVlOiBzdHJpbmcpIHtcbiAgICAvLyBNYXAgb3B0aW9ucyB0byBudW1lcmljIHZhbHVlcyBmb3IgYW5hbHl0aWNzIChzdHJpbmdzIG5vdCBhbGxvd2VkIGluIGxvZ0V2ZW50KVxuICAgIGNvbnN0IG9wdGlvbkluZGV4OiBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+ID0ge1xuICAgICAgeWVzOiAxLFxuICAgICAgJ3llcy1hcHBseS1zdWdnZXN0aW9ucyc6IDIsXG4gICAgICAneWVzLXByZWZpeC1lZGl0ZWQnOiAyLFxuICAgICAgbm86IDMsXG4gICAgfVxuICAgIGxvZ0V2ZW50KCd0ZW5ndV9wZXJtaXNzaW9uX3JlcXVlc3Rfb3B0aW9uX3NlbGVjdGVkJywge1xuICAgICAgb3B0aW9uX2luZGV4OiBvcHRpb25JbmRleFt2YWx1ZV0sXG4gICAgICBleHBsYWluZXJfdmlzaWJsZTogZXhwbGFpbmVyU3RhdGUudmlzaWJsZSxcbiAgICB9KVxuXG4gICAgY29uc3QgdG9vbE5hbWVGb3JBbmFseXRpY3MgPSBzYW5pdGl6ZVRvb2xOYW1lRm9yQW5hbHl0aWNzKFxuICAgICAgdG9vbFVzZUNvbmZpcm0udG9vbC5uYW1lLFxuICAgICkgYXMgQW5hbHl0aWNzTWV0YWRhdGFfSV9WRVJJRklFRF9USElTX0lTX05PVF9DT0RFX09SX0ZJTEVQQVRIU1xuXG4gICAgaWYgKHZhbHVlID09PSAneWVzLXByZWZpeC1lZGl0ZWQnKSB7XG4gICAgICBjb25zdCB0cmltbWVkUHJlZml4ID0gKGVkaXRhYmxlUHJlZml4ID8/ICcnKS50cmltKClcbiAgICAgIGxvZ1VuYXJ5UGVybWlzc2lvbkV2ZW50KCd0b29sX3VzZV9zaW5nbGUnLCB0b29sVXNlQ29uZmlybSwgJ2FjY2VwdCcpXG4gICAgICBpZiAoIXRyaW1tZWRQcmVmaXgpIHtcbiAgICAgICAgdG9vbFVzZUNvbmZpcm0ub25BbGxvdyh0b29sVXNlQ29uZmlybS5pbnB1dCwgW10pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBwcmVmaXhVcGRhdGVzOiBQZXJtaXNzaW9uVXBkYXRlW10gPSBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogJ2FkZFJ1bGVzJyxcbiAgICAgICAgICAgIHJ1bGVzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0b29sTmFtZTogUG93ZXJTaGVsbFRvb2wubmFtZSxcbiAgICAgICAgICAgICAgICBydWxlQ29udGVudDogdHJpbW1lZFByZWZpeCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBiZWhhdmlvcjogJ2FsbG93JyxcbiAgICAgICAgICAgIGRlc3RpbmF0aW9uOiAnbG9jYWxTZXR0aW5ncycsXG4gICAgICAgICAgfSxcbiAgICAgICAgXVxuICAgICAgICB0b29sVXNlQ29uZmlybS5vbkFsbG93KHRvb2xVc2VDb25maXJtLmlucHV0LCBwcmVmaXhVcGRhdGVzKVxuICAgICAgfVxuICAgICAgb25Eb25lKClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHN3aXRjaCAodmFsdWUpIHtcbiAgICAgIGNhc2UgJ3llcyc6IHtcbiAgICAgICAgY29uc3QgdHJpbW1lZEZlZWRiYWNrID0gYWNjZXB0RmVlZGJhY2sudHJpbSgpXG4gICAgICAgIGxvZ1VuYXJ5UGVybWlzc2lvbkV2ZW50KCd0b29sX3VzZV9zaW5nbGUnLCB0b29sVXNlQ29uZmlybSwgJ2FjY2VwdCcpXG4gICAgICAgIC8vIExvZyBhY2NlcHQgc3VibWlzc2lvbiB3aXRoIGZlZWRiYWNrIGNvbnRleHRcbiAgICAgICAgbG9nRXZlbnQoJ3Rlbmd1X2FjY2VwdF9zdWJtaXR0ZWQnLCB7XG4gICAgICAgICAgdG9vbE5hbWU6IHRvb2xOYW1lRm9yQW5hbHl0aWNzLFxuICAgICAgICAgIGlzTWNwOiB0b29sVXNlQ29uZmlybS50b29sLmlzTWNwID8/IGZhbHNlLFxuICAgICAgICAgIGhhc19pbnN0cnVjdGlvbnM6ICEhdHJpbW1lZEZlZWRiYWNrLFxuICAgICAgICAgIGluc3RydWN0aW9uc19sZW5ndGg6IHRyaW1tZWRGZWVkYmFjay5sZW5ndGgsXG4gICAgICAgICAgZW50ZXJlZF9mZWVkYmFja19tb2RlOiB5ZXNGZWVkYmFja01vZGVFbnRlcmVkLFxuICAgICAgICB9KVxuICAgICAgICB0b29sVXNlQ29uZmlybS5vbkFsbG93KFxuICAgICAgICAgIHRvb2xVc2VDb25maXJtLmlucHV0LFxuICAgICAgICAgIFtdLFxuICAgICAgICAgIHRyaW1tZWRGZWVkYmFjayB8fCB1bmRlZmluZWQsXG4gICAgICAgIClcbiAgICAgICAgb25Eb25lKClcbiAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICAgIGNhc2UgJ3llcy1hcHBseS1zdWdnZXN0aW9ucyc6IHtcbiAgICAgICAgbG9nVW5hcnlQZXJtaXNzaW9uRXZlbnQoJ3Rvb2xfdXNlX3NpbmdsZScsIHRvb2xVc2VDb25maXJtLCAnYWNjZXB0JylcbiAgICAgICAgLy8gRXh0cmFjdCBzdWdnZXN0aW9ucyBpZiBwcmVzZW50ICh3b3JrcyBmb3IgYm90aCAnYXNrJyBhbmQgJ3Bhc3N0aHJvdWdoJyBiZWhhdmlvcnMpXG4gICAgICAgIGNvbnN0IHBlcm1pc3Npb25VcGRhdGVzID1cbiAgICAgICAgICAnc3VnZ2VzdGlvbnMnIGluIHRvb2xVc2VDb25maXJtLnBlcm1pc3Npb25SZXN1bHRcbiAgICAgICAgICAgID8gdG9vbFVzZUNvbmZpcm0ucGVybWlzc2lvblJlc3VsdC5zdWdnZXN0aW9ucyB8fCBbXVxuICAgICAgICAgICAgOiBbXVxuICAgICAgICB0b29sVXNlQ29uZmlybS5vbkFsbG93KHRvb2xVc2VDb25maXJtLmlucHV0LCBwZXJtaXNzaW9uVXBkYXRlcylcbiAgICAgICAgb25Eb25lKClcbiAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICAgIGNhc2UgJ25vJzoge1xuICAgICAgICBjb25zdCB0cmltbWVkRmVlZGJhY2sgPSByZWplY3RGZWVkYmFjay50cmltKClcblxuICAgICAgICAvLyBMb2cgcmVqZWN0IHN1Ym1pc3Npb24gd2l0aCBmZWVkYmFjayBjb250ZXh0XG4gICAgICAgIGxvZ0V2ZW50KCd0ZW5ndV9yZWplY3Rfc3VibWl0dGVkJywge1xuICAgICAgICAgIHRvb2xOYW1lOiB0b29sTmFtZUZvckFuYWx5dGljcyxcbiAgICAgICAgICBpc01jcDogdG9vbFVzZUNvbmZpcm0udG9vbC5pc01jcCA/PyBmYWxzZSxcbiAgICAgICAgICBoYXNfaW5zdHJ1Y3Rpb25zOiAhIXRyaW1tZWRGZWVkYmFjayxcbiAgICAgICAgICBpbnN0cnVjdGlvbnNfbGVuZ3RoOiB0cmltbWVkRmVlZGJhY2subGVuZ3RoLFxuICAgICAgICAgIGVudGVyZWRfZmVlZGJhY2tfbW9kZTogbm9GZWVkYmFja01vZGVFbnRlcmVkLFxuICAgICAgICB9KVxuXG4gICAgICAgIC8vIFByb2Nlc3MgcmVqZWN0aW9uICh3aXRoIG9yIHdpdGhvdXQgZmVlZGJhY2spXG4gICAgICAgIGhhbmRsZVJlamVjdCh0cmltbWVkRmVlZGJhY2sgfHwgdW5kZWZpbmVkKVxuICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiAoXG4gICAgPFBlcm1pc3Npb25EaWFsb2cgd29ya2VyQmFkZ2U9e3dvcmtlckJhZGdlfSB0aXRsZT1cIlBvd2VyU2hlbGwgY29tbWFuZFwiPlxuICAgICAgPEJveCBmbGV4RGlyZWN0aW9uPVwiY29sdW1uXCIgcGFkZGluZ1g9ezJ9IHBhZGRpbmdZPXsxfT5cbiAgICAgICAgPFRleHQgZGltQ29sb3I9e2V4cGxhaW5lclN0YXRlLnZpc2libGV9PlxuICAgICAgICAgIHtQb3dlclNoZWxsVG9vbC5yZW5kZXJUb29sVXNlTWVzc2FnZShcbiAgICAgICAgICAgIHsgY29tbWFuZCwgZGVzY3JpcHRpb24gfSxcbiAgICAgICAgICAgIHsgdGhlbWUsIHZlcmJvc2U6IHRydWUgfSwgLy8gYWx3YXlzIHNob3cgdGhlIGZ1bGwgY29tbWFuZFxuICAgICAgICAgICl9XG4gICAgICAgIDwvVGV4dD5cbiAgICAgICAgeyFleHBsYWluZXJTdGF0ZS52aXNpYmxlICYmIChcbiAgICAgICAgICA8VGV4dCBkaW1Db2xvcj57dG9vbFVzZUNvbmZpcm0uZGVzY3JpcHRpb259PC9UZXh0PlxuICAgICAgICApfVxuICAgICAgICA8UGVybWlzc2lvbkV4cGxhaW5lckNvbnRlbnRcbiAgICAgICAgICB2aXNpYmxlPXtleHBsYWluZXJTdGF0ZS52aXNpYmxlfVxuICAgICAgICAgIHByb21pc2U9e2V4cGxhaW5lclN0YXRlLnByb21pc2V9XG4gICAgICAgIC8+XG4gICAgICA8L0JveD5cbiAgICAgIHtzaG93UGVybWlzc2lvbkRlYnVnID8gKFxuICAgICAgICA8PlxuICAgICAgICAgIDxQZXJtaXNzaW9uRGVjaXNpb25EZWJ1Z0luZm9cbiAgICAgICAgICAgIHBlcm1pc3Npb25SZXN1bHQ9e3Rvb2xVc2VDb25maXJtLnBlcm1pc3Npb25SZXN1bHR9XG4gICAgICAgICAgICB0b29sTmFtZT1cIlBvd2VyU2hlbGxcIlxuICAgICAgICAgIC8+XG4gICAgICAgICAge3Rvb2xVc2VDb250ZXh0Lm9wdGlvbnMuZGVidWcgJiYgKFxuICAgICAgICAgICAgPEJveCBqdXN0aWZ5Q29udGVudD1cImZsZXgtZW5kXCIgbWFyZ2luVG9wPXsxfT5cbiAgICAgICAgICAgICAgPFRleHQgZGltQ29sb3I+Q3RybC1EIHRvIGhpZGUgZGVidWcgaW5mbzwvVGV4dD5cbiAgICAgICAgICAgIDwvQm94PlxuICAgICAgICAgICl9XG4gICAgICAgIDwvPlxuICAgICAgKSA6IChcbiAgICAgICAgPD5cbiAgICAgICAgICA8Qm94IGZsZXhEaXJlY3Rpb249XCJjb2x1bW5cIj5cbiAgICAgICAgICAgIDxQZXJtaXNzaW9uUnVsZUV4cGxhbmF0aW9uXG4gICAgICAgICAgICAgIHBlcm1pc3Npb25SZXN1bHQ9e3Rvb2xVc2VDb25maXJtLnBlcm1pc3Npb25SZXN1bHR9XG4gICAgICAgICAgICAgIHRvb2xUeXBlPVwiY29tbWFuZFwiXG4gICAgICAgICAgICAvPlxuICAgICAgICAgICAge2Rlc3RydWN0aXZlV2FybmluZyAmJiAoXG4gICAgICAgICAgICAgIDxCb3ggbWFyZ2luQm90dG9tPXsxfT5cbiAgICAgICAgICAgICAgICA8VGV4dCBjb2xvcj1cIndhcm5pbmdcIj57ZGVzdHJ1Y3RpdmVXYXJuaW5nfTwvVGV4dD5cbiAgICAgICAgICAgICAgPC9Cb3g+XG4gICAgICAgICAgICApfVxuICAgICAgICAgICAgPFRleHQ+RG8geW91IHdhbnQgdG8gcHJvY2VlZD88L1RleHQ+XG4gICAgICAgICAgICA8U2VsZWN0XG4gICAgICAgICAgICAgIG9wdGlvbnM9e29wdGlvbnN9XG4gICAgICAgICAgICAgIGlubGluZURlc2NyaXB0aW9uc1xuICAgICAgICAgICAgICBvbkNoYW5nZT17b25TZWxlY3R9XG4gICAgICAgICAgICAgIG9uQ2FuY2VsPXsoKSA9PiBoYW5kbGVSZWplY3QoKX1cbiAgICAgICAgICAgICAgb25Gb2N1cz17aGFuZGxlRm9jdXN9XG4gICAgICAgICAgICAgIG9uSW5wdXRNb2RlVG9nZ2xlPXtoYW5kbGVJbnB1dE1vZGVUb2dnbGV9XG4gICAgICAgICAgICAvPlxuICAgICAgICAgIDwvQm94PlxuICAgICAgICAgIDxCb3gganVzdGlmeUNvbnRlbnQ9XCJzcGFjZS1iZXR3ZWVuXCIgbWFyZ2luVG9wPXsxfT5cbiAgICAgICAgICAgIDxUZXh0IGRpbUNvbG9yPlxuICAgICAgICAgICAgICBFc2MgdG8gY2FuY2VsXG4gICAgICAgICAgICAgIHsoKGZvY3VzZWRPcHRpb24gPT09ICd5ZXMnICYmICF5ZXNJbnB1dE1vZGUpIHx8XG4gICAgICAgICAgICAgICAgKGZvY3VzZWRPcHRpb24gPT09ICdubycgJiYgIW5vSW5wdXRNb2RlKSkgJiZcbiAgICAgICAgICAgICAgICAnIMK3IFRhYiB0byBhbWVuZCd9XG4gICAgICAgICAgICAgIHtleHBsYWluZXJTdGF0ZS5lbmFibGVkICYmXG4gICAgICAgICAgICAgICAgYCDCtyBjdHJsK2UgdG8gJHtleHBsYWluZXJTdGF0ZS52aXNpYmxlID8gJ2hpZGUnIDogJ2V4cGxhaW4nfWB9XG4gICAgICAgICAgICA8L1RleHQ+XG4gICAgICAgICAgICB7dG9vbFVzZUNvbnRleHQub3B0aW9ucy5kZWJ1ZyAmJiAoXG4gICAgICAgICAgICAgIDxUZXh0IGRpbUNvbG9yPkN0cmwrZCB0byBzaG93IGRlYnVnIGluZm88L1RleHQ+XG4gICAgICAgICAgICApfVxuICAgICAgICAgIDwvQm94PlxuICAgICAgICA8Lz5cbiAgICAg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