/ components / permissions / PermissionPrompt.tsx
PermissionPrompt.tsx
  1  import { c as _c } from "react/compiler-runtime";
  2  import React, { type ReactNode, useCallback, useMemo, useState } from 'react';
  3  import { Box, Text } from '../../ink.js';
  4  import type { KeybindingAction } from '../../keybindings/types.js';
  5  import { useKeybindings } from '../../keybindings/useKeybinding.js';
  6  import { type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, logEvent } from '../../services/analytics/index.js';
  7  import { useSetAppState } from '../../state/AppState.js';
  8  import { type OptionWithDescription, Select } from '../CustomSelect/select.js';
  9  export type FeedbackType = 'accept' | 'reject';
 10  export type PermissionPromptOption<T extends string> = {
 11    value: T;
 12    label: ReactNode;
 13    feedbackConfig?: {
 14      type: FeedbackType;
 15      placeholder?: string;
 16    };
 17    keybinding?: KeybindingAction;
 18  };
 19  export type ToolAnalyticsContext = {
 20    toolName: string;
 21    isMcp: boolean;
 22  };
 23  export type PermissionPromptProps<T extends string> = {
 24    options: PermissionPromptOption<T>[];
 25    onSelect: (value: T, feedback?: string) => void;
 26    onCancel?: () => void;
 27    question?: string | ReactNode;
 28    toolAnalyticsContext?: ToolAnalyticsContext;
 29  };
 30  const DEFAULT_PLACEHOLDERS: Record<FeedbackType, string> = {
 31    accept: 'tell Claude what to do next',
 32    reject: 'tell Claude what to do differently'
 33  };
 34  
 35  /**
 36   * Shared component for permission prompts with optional feedback input.
 37   *
 38   * Handles:
 39   * - "Do you want to proceed?" question with optional Tab hint
 40   * - Feature flag check for feedback capability
 41   * - Input mode toggling (Tab to expand feedback input)
 42   * - Analytics events for feedback interactions
 43   * - Transforming options to Select-compatible format
 44   */
 45  export function PermissionPrompt(t0) {
 46    const $ = _c(54);
 47    const {
 48      options,
 49      onSelect,
 50      onCancel,
 51      question: t1,
 52      toolAnalyticsContext
 53    } = t0;
 54    const question = t1 === undefined ? "Do you want to proceed?" : t1;
 55    const setAppState = useSetAppState();
 56    const [acceptFeedback, setAcceptFeedback] = useState("");
 57    const [rejectFeedback, setRejectFeedback] = useState("");
 58    const [acceptInputMode, setAcceptInputMode] = useState(false);
 59    const [rejectInputMode, setRejectInputMode] = useState(false);
 60    const [focusedValue, setFocusedValue] = useState(null);
 61    const [acceptFeedbackModeEntered, setAcceptFeedbackModeEntered] = useState(false);
 62    const [rejectFeedbackModeEntered, setRejectFeedbackModeEntered] = useState(false);
 63    let t2;
 64    if ($[0] !== focusedValue || $[1] !== options) {
 65      let t3;
 66      if ($[3] !== focusedValue) {
 67        t3 = opt => opt.value === focusedValue;
 68        $[3] = focusedValue;
 69        $[4] = t3;
 70      } else {
 71        t3 = $[4];
 72      }
 73      t2 = options.find(t3);
 74      $[0] = focusedValue;
 75      $[1] = options;
 76      $[2] = t2;
 77    } else {
 78      t2 = $[2];
 79    }
 80    const focusedOption = t2;
 81    const focusedFeedbackType = focusedOption?.feedbackConfig?.type;
 82    const showTabHint = focusedFeedbackType === "accept" && !acceptInputMode || focusedFeedbackType === "reject" && !rejectInputMode;
 83    let t3;
 84    if ($[5] !== acceptInputMode || $[6] !== options || $[7] !== rejectInputMode) {
 85      let t4;
 86      if ($[9] !== acceptInputMode || $[10] !== rejectInputMode) {
 87        t4 = opt_0 => {
 88          const {
 89            value,
 90            label,
 91            feedbackConfig
 92          } = opt_0;
 93          if (!feedbackConfig) {
 94            return {
 95              label,
 96              value
 97            };
 98          }
 99          const {
100            type,
101            placeholder
102          } = feedbackConfig;
103          const isInputMode = type === "accept" ? acceptInputMode : rejectInputMode;
104          const onChange = type === "accept" ? setAcceptFeedback : setRejectFeedback;
105          const defaultPlaceholder = DEFAULT_PLACEHOLDERS[type];
106          if (isInputMode) {
107            return {
108              type: "input" as const,
109              label,
110              value,
111              placeholder: placeholder ?? defaultPlaceholder,
112              onChange,
113              allowEmptySubmitToCancel: true
114            };
115          }
116          return {
117            label,
118            value
119          };
120        };
121        $[9] = acceptInputMode;
122        $[10] = rejectInputMode;
123        $[11] = t4;
124      } else {
125        t4 = $[11];
126      }
127      t3 = options.map(t4);
128      $[5] = acceptInputMode;
129      $[6] = options;
130      $[7] = rejectInputMode;
131      $[8] = t3;
132    } else {
133      t3 = $[8];
134    }
135    const selectOptions = t3;
136    let t4;
137    if ($[12] !== acceptInputMode || $[13] !== options || $[14] !== rejectInputMode || $[15] !== toolAnalyticsContext?.isMcp || $[16] !== toolAnalyticsContext?.toolName) {
138      t4 = value_0 => {
139        const option = options.find(opt_1 => opt_1.value === value_0);
140        if (!option?.feedbackConfig) {
141          return;
142        }
143        const {
144          type: type_0
145        } = option.feedbackConfig;
146        const analyticsProps = {
147          toolName: toolAnalyticsContext?.toolName as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
148          isMcp: toolAnalyticsContext?.isMcp ?? false
149        };
150        if (type_0 === "accept") {
151          if (acceptInputMode) {
152            setAcceptInputMode(false);
153            logEvent("tengu_accept_feedback_mode_collapsed", analyticsProps);
154          } else {
155            setAcceptInputMode(true);
156            setAcceptFeedbackModeEntered(true);
157            logEvent("tengu_accept_feedback_mode_entered", analyticsProps);
158          }
159        } else {
160          if (type_0 === "reject") {
161            if (rejectInputMode) {
162              setRejectInputMode(false);
163              logEvent("tengu_reject_feedback_mode_collapsed", analyticsProps);
164            } else {
165              setRejectInputMode(true);
166              setRejectFeedbackModeEntered(true);
167              logEvent("tengu_reject_feedback_mode_entered", analyticsProps);
168            }
169          }
170        }
171      };
172      $[12] = acceptInputMode;
173      $[13] = options;
174      $[14] = rejectInputMode;
175      $[15] = toolAnalyticsContext?.isMcp;
176      $[16] = toolAnalyticsContext?.toolName;
177      $[17] = t4;
178    } else {
179      t4 = $[17];
180    }
181    const handleInputModeToggle = t4;
182    let t5;
183    if ($[18] !== acceptFeedback || $[19] !== acceptFeedbackModeEntered || $[20] !== onSelect || $[21] !== options || $[22] !== rejectFeedback || $[23] !== rejectFeedbackModeEntered || $[24] !== toolAnalyticsContext?.isMcp || $[25] !== toolAnalyticsContext?.toolName) {
184      t5 = value_1 => {
185        const option_0 = options.find(opt_2 => opt_2.value === value_1);
186        if (!option_0) {
187          return;
188        }
189        let feedback;
190        if (option_0.feedbackConfig) {
191          const rawFeedback = option_0.feedbackConfig.type === "accept" ? acceptFeedback : rejectFeedback;
192          const trimmedFeedback = rawFeedback.trim();
193          if (trimmedFeedback) {
194            feedback = trimmedFeedback;
195          }
196          const analyticsProps_0 = {
197            toolName: toolAnalyticsContext?.toolName as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
198            isMcp: toolAnalyticsContext?.isMcp ?? false,
199            has_instructions: !!trimmedFeedback,
200            instructions_length: trimmedFeedback?.length ?? 0,
201            entered_feedback_mode: option_0.feedbackConfig.type === "accept" ? acceptFeedbackModeEntered : rejectFeedbackModeEntered
202          };
203          if (option_0.feedbackConfig.type === "accept") {
204            logEvent("tengu_accept_submitted", analyticsProps_0);
205          } else {
206            if (option_0.feedbackConfig.type === "reject") {
207              logEvent("tengu_reject_submitted", analyticsProps_0);
208            }
209          }
210        }
211        onSelect(value_1, feedback);
212      };
213      $[18] = acceptFeedback;
214      $[19] = acceptFeedbackModeEntered;
215      $[20] = onSelect;
216      $[21] = options;
217      $[22] = rejectFeedback;
218      $[23] = rejectFeedbackModeEntered;
219      $[24] = toolAnalyticsContext?.isMcp;
220      $[25] = toolAnalyticsContext?.toolName;
221      $[26] = t5;
222    } else {
223      t5 = $[26];
224    }
225    const handleSelect = t5;
226    let handlers;
227    if ($[27] !== handleSelect || $[28] !== options) {
228      handlers = {};
229      for (const opt_3 of options) {
230        if (opt_3.keybinding) {
231          handlers[opt_3.keybinding] = () => handleSelect(opt_3.value);
232        }
233      }
234      $[27] = handleSelect;
235      $[28] = options;
236      $[29] = handlers;
237    } else {
238      handlers = $[29];
239    }
240    const keybindingHandlers = handlers;
241    let t6;
242    if ($[30] === Symbol.for("react.memo_cache_sentinel")) {
243      t6 = {
244        context: "Confirmation"
245      };
246      $[30] = t6;
247    } else {
248      t6 = $[30];
249    }
250    useKeybindings(keybindingHandlers, t6);
251    let t7;
252    if ($[31] !== onCancel || $[32] !== setAppState) {
253      t7 = () => {
254        logEvent("tengu_permission_request_escape", {});
255        setAppState(_temp);
256        onCancel?.();
257      };
258      $[31] = onCancel;
259      $[32] = setAppState;
260      $[33] = t7;
261    } else {
262      t7 = $[33];
263    }
264    const handleCancel = t7;
265    let t8;
266    if ($[34] !== question) {
267      t8 = typeof question === "string" ? <Text>{question}</Text> : question;
268      $[34] = question;
269      $[35] = t8;
270    } else {
271      t8 = $[35];
272    }
273    let t9;
274    if ($[36] !== acceptFeedback || $[37] !== acceptInputMode || $[38] !== options || $[39] !== rejectFeedback || $[40] !== rejectInputMode) {
275      t9 = value_2 => {
276        const newOption = options.find(opt_4 => opt_4.value === value_2);
277        if (newOption?.feedbackConfig?.type !== "accept" && acceptInputMode && !acceptFeedback.trim()) {
278          setAcceptInputMode(false);
279        }
280        if (newOption?.feedbackConfig?.type !== "reject" && rejectInputMode && !rejectFeedback.trim()) {
281          setRejectInputMode(false);
282        }
283        setFocusedValue(value_2);
284      };
285      $[36] = acceptFeedback;
286      $[37] = acceptInputMode;
287      $[38] = options;
288      $[39] = rejectFeedback;
289      $[40] = rejectInputMode;
290      $[41] = t9;
291    } else {
292      t9 = $[41];
293    }
294    let t10;
295    if ($[42] !== handleCancel || $[43] !== handleInputModeToggle || $[44] !== handleSelect || $[45] !== selectOptions || $[46] !== t9) {
296      t10 = <Select options={selectOptions} inlineDescriptions={true} onChange={handleSelect} onCancel={handleCancel} onFocus={t9} onInputModeToggle={handleInputModeToggle} />;
297      $[42] = handleCancel;
298      $[43] = handleInputModeToggle;
299      $[44] = handleSelect;
300      $[45] = selectOptions;
301      $[46] = t9;
302      $[47] = t10;
303    } else {
304      t10 = $[47];
305    }
306    const t11 = showTabHint && " \xB7 Tab to amend";
307    let t12;
308    if ($[48] !== t11) {
309      t12 = <Box marginTop={1}><Text dimColor={true}>Esc to cancel{t11}</Text></Box>;
310      $[48] = t11;
311      $[49] = t12;
312    } else {
313      t12 = $[49];
314    }
315    let t13;
316    if ($[50] !== t10 || $[51] !== t12 || $[52] !== t8) {
317      t13 = <Box flexDirection="column">{t8}{t10}{t12}</Box>;
318      $[50] = t10;
319      $[51] = t12;
320      $[52] = t8;
321      $[53] = t13;
322    } else {
323      t13 = $[53];
324    }
325    return t13;
326  }
327  function _temp(prev) {
328    return {
329      ...prev,
330      attribution: {
331        ...prev.attribution,
332        escapeCount: prev.attribution.escapeCount + 1
333      }
334    };
335  }
336  //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSZWFjdCIsIlJlYWN0Tm9kZSIsInVzZUNhbGxiYWNrIiwidXNlTWVtbyIsInVzZVN0YXRlIiwiQm94IiwiVGV4dCIsIktleWJpbmRpbmdBY3Rpb24iLCJ1c2VLZXliaW5kaW5ncyIsIkFuYWx5dGljc01ldGFkYXRhX0lfVkVSSUZJRURfVEhJU19JU19OT1RfQ09ERV9PUl9GSUxFUEFUSFMiLCJsb2dFdmVudCIsInVzZVNldEFwcFN0YXRlIiwiT3B0aW9uV2l0aERlc2NyaXB0aW9uIiwiU2VsZWN0IiwiRmVlZGJhY2tUeXBlIiwiUGVybWlzc2lvblByb21wdE9wdGlvbiIsInZhbHVlIiwiVCIsImxhYmVsIiwiZmVlZGJhY2tDb25maWciLCJ0eXBlIiwicGxhY2Vob2xkZXIiLCJrZXliaW5kaW5nIiwiVG9vbEFuYWx5dGljc0NvbnRleHQiLCJ0b29sTmFtZSIsImlzTWNwIiwiUGVybWlzc2lvblByb21wdFByb3BzIiwib3B0aW9ucyIsIm9uU2VsZWN0IiwiZmVlZGJhY2siLCJvbkNhbmNlbCIsInF1ZXN0aW9uIiwidG9vbEFuYWx5dGljc0NvbnRleHQiLCJERUZBVUxUX1BMQUNFSE9MREVSUyIsIlJlY29yZCIsImFjY2VwdCIsInJlamVjdCIsIlBlcm1pc3Npb25Qcm9tcHQiLCJ0MCIsIiQiLCJfYyIsInQxIiwidW5kZWZpbmVkIiwic2V0QXBwU3RhdGUiLCJhY2NlcHRGZWVkYmFjayIsInNldEFjY2VwdEZlZWRiYWNrIiwicmVqZWN0RmVlZGJhY2siLCJzZXRSZWplY3RGZWVkYmFjayIsImFjY2VwdElucHV0TW9kZSIsInNldEFjY2VwdElucHV0TW9kZSIsInJlamVjdElucHV0TW9kZSIsInNldFJlamVjdElucHV0TW9kZSIsImZvY3VzZWRWYWx1ZSIsInNldEZvY3VzZWRWYWx1ZSIsImFjY2VwdEZlZWRiYWNrTW9kZUVudGVyZWQiLCJzZXRBY2NlcHRGZWVkYmFja01vZGVFbnRlcmVkIiwicmVqZWN0RmVlZGJhY2tNb2RlRW50ZXJlZCIsInNldFJlamVjdEZlZWRiYWNrTW9kZUVudGVyZWQiLCJ0MiIsInQzIiwib3B0IiwiZmluZCIsImZvY3VzZWRPcHRpb24iLCJmb2N1c2VkRmVlZGJhY2tUeXBlIiwic2hvd1RhYkhpbnQiLCJ0NCIsIm9wdF8wIiwiaXNJbnB1dE1vZGUiLCJvbkNoYW5nZSIsImRlZmF1bHRQbGFjZWhvbGRlciIsImNvbnN0IiwiYWxsb3dFbXB0eVN1Ym1pdFRvQ2FuY2VsIiwibWFwIiwic2VsZWN0T3B0aW9ucyIsInZhbHVlXzAiLCJvcHRpb24iLCJvcHRfMSIsInR5cGVfMCIsImFuYWx5dGljc1Byb3BzIiwiaGFuZGxlSW5wdXRNb2RlVG9nZ2xlIiwidDUiLCJ2YWx1ZV8xIiwib3B0aW9uXzAiLCJvcHRfMiIsInJhd0ZlZWRiYWNrIiwidHJpbW1lZEZlZWRiYWNrIiwidHJpbSIsImFuYWx5dGljc1Byb3BzXzAiLCJoYXNfaW5zdHJ1Y3Rpb25zIiwiaW5zdHJ1Y3Rpb25zX2xlbmd0aCIsImxlbmd0aCIsImVudGVyZWRfZmVlZGJhY2tfbW9kZSIsImhhbmRsZVNlbGVjdCIsImhhbmRsZXJzIiwib3B0XzMiLCJrZXliaW5kaW5nSGFuZGxlcnMiLCJ0NiIsIlN5bWJvbCIsImZvciIsImNvbnRleHQiLCJ0NyIsIl90ZW1wIiwiaGFuZGxlQ2FuY2VsIiwidDgiLCJ0OSIsInZhbHVlXzIiLCJuZXdPcHRpb24iLCJvcHRfNCIsInQxMCIsInQxMSIsInQxMiIsInQxMyIsInByZXYiLCJhdHRyaWJ1dGlvbiIsImVzY2FwZUNvdW50Il0sInNvdXJjZXMiOlsiUGVybWlzc2lvblByb21wdC50c3giXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFJlYWN0LCB7IHR5cGUgUmVhY3ROb2RlLCB1c2VDYWxsYmFjaywgdXNlTWVtbywgdXNlU3RhdGUgfSBmcm9tICdyZWFjdCdcbmltcG9ydCB7IEJveCwgVGV4dCB9IGZyb20gJy4uLy4uL2luay5qcydcbmltcG9ydCB0eXBlIHsgS2V5YmluZGluZ0FjdGlvbiB9IGZyb20gJy4uLy4uL2tleWJpbmRpbmdzL3R5cGVzLmpzJ1xuaW1wb3J0IHsgdXNlS2V5YmluZGluZ3MgfSBmcm9tICcuLi8uLi9rZXliaW5kaW5ncy91c2VLZXliaW5kaW5nLmpzJ1xuaW1wb3J0IHtcbiAgdHlwZSBBbmFseXRpY3NNZXRhZGF0YV9JX1ZFUklGSUVEX1RISVNfSVNfTk9UX0NPREVfT1JfRklMRVBBVEhTLFxuICBsb2dFdmVudCxcbn0gZnJvbSAnLi4vLi4vc2VydmljZXMvYW5hbHl0aWNzL2luZGV4LmpzJ1xuaW1wb3J0IHsgdXNlU2V0QXBwU3RhdGUgfSBmcm9tICcuLi8uLi9zdGF0ZS9BcHBTdGF0ZS5qcydcbmltcG9ydCB7IHR5cGUgT3B0aW9uV2l0aERlc2NyaXB0aW9uLCBTZWxlY3QgfSBmcm9tICcuLi9DdXN0b21TZWxlY3Qvc2VsZWN0LmpzJ1xuXG5leHBvcnQgdHlwZSBGZWVkYmFja1R5cGUgPSAnYWNjZXB0JyB8ICdyZWplY3QnXG5cbmV4cG9ydCB0eXBlIFBlcm1pc3Npb25Qcm9tcHRPcHRpb248VCBleHRlbmRzIHN0cmluZz4gPSB7XG4gIHZhbHVlOiBUXG4gIGxhYmVsOiBSZWFjdE5vZGVcbiAgZmVlZGJhY2tDb25maWc/OiB7XG4gICAgdHlwZTogRmVlZGJhY2tUeXBlXG4gICAgcGxhY2Vob2xkZXI/OiBzdHJpbmdcbiAgfVxuICBrZXliaW5kaW5nPzogS2V5YmluZGluZ0FjdGlvblxufVxuXG5leHBvcnQgdHlwZSBUb29sQW5hbHl0aWNzQ29udGV4dCA9IHtcbiAgdG9vbE5hbWU6IHN0cmluZ1xuICBpc01jcDogYm9vbGVhblxufVxuXG5leHBvcnQgdHlwZSBQZXJtaXNzaW9uUHJvbXB0UHJvcHM8VCBleHRlbmRzIHN0cmluZz4gPSB7XG4gIG9wdGlvbnM6IFBlcm1pc3Npb25Qcm9tcHRPcHRpb248VD5bXVxuICBvblNlbGVjdDogKHZhbHVlOiBULCBmZWVkYmFjaz86IHN0cmluZykgPT4gdm9pZFxuICBvbkNhbmNlbD86ICgpID0+IHZvaWRcbiAgcXVlc3Rpb24/OiBzdHJpbmcgfCBSZWFjdE5vZGVcbiAgdG9vbEFuYWx5dGljc0NvbnRleHQ/OiBUb29sQW5hbHl0aWNzQ29udGV4dFxufVxuXG5jb25zdCBERUZBVUxUX1BMQUNFSE9MREVSUzogUmVjb3JkPEZlZWRiYWNrVHlwZSwgc3RyaW5nPiA9IHtcbiAgYWNjZXB0OiAndGVsbCBDbGF1ZGUgd2hhdCB0byBkbyBuZXh0JyxcbiAgcmVqZWN0OiAndGVsbCBDbGF1ZGUgd2hhdCB0byBkbyBkaWZmZXJlbnRseScsXG59XG5cbi8qKlxuICogU2hhcmVkIGNvbXBvbmVudCBmb3IgcGVybWlzc2lvbiBwcm9tcHRzIHdpdGggb3B0aW9uYWwgZmVlZGJhY2sgaW5wdXQuXG4gKlxuICogSGFuZGxlczpcbiAqIC0gXCJEbyB5b3Ugd2FudCB0byBwcm9jZWVkP1wiIHF1ZXN0aW9uIHdpdGggb3B0aW9uYWwgVGFiIGhpbnRcbiAqIC0gRmVhdHVyZSBmbGFnIGNoZWNrIGZvciBmZWVkYmFjayBjYXBhYmlsaXR5XG4gKiAtIElucHV0IG1vZGUgdG9nZ2xpbmcgKFRhYiB0byBleHBhbmQgZmVlZGJhY2sgaW5wdXQpXG4gKiAtIEFuYWx5dGljcyBldmVudHMgZm9yIGZlZWRiYWNrIGludGVyYWN0aW9uc1xuICogLSBUcmFuc2Zvcm1pbmcgb3B0aW9ucyB0byBTZWxlY3QtY29tcGF0aWJsZSBmb3JtYXRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFBlcm1pc3Npb25Qcm9tcHQ8VCBleHRlbmRzIHN0cmluZz4oe1xuICBvcHRpb25zLFxuICBvblNlbGVjdCxcbiAgb25DYW5jZWwsXG4gIHF1ZXN0aW9uID0gJ0RvIHlvdSB3YW50IHRvIHByb2NlZWQ/JyxcbiAgdG9vbEFuYWx5dGljc0NvbnRleHQsXG59OiBQZXJtaXNzaW9uUHJvbXB0UHJvcHM8VD4pOiBSZWFjdC5SZWFjdE5vZGUge1xuICBjb25zdCBzZXRBcHBTdGF0ZSA9IHVzZVNldEFwcFN0YXRlKClcbiAgY29uc3QgW2FjY2VwdEZlZWRiYWNrLCBzZXRBY2NlcHRGZWVkYmFja10gPSB1c2VTdGF0ZSgnJylcbiAgY29uc3QgW3JlamVjdEZlZWRiYWNrLCBzZXRSZWplY3RGZWVkYmFja10gPSB1c2VTdGF0ZSgnJylcbiAgY29uc3QgW2FjY2VwdElucHV0TW9kZSwgc2V0QWNjZXB0SW5wdXRNb2RlXSA9IHVzZVN0YXRlKGZhbHNlKVxuICBjb25zdCBbcmVqZWN0SW5wdXRNb2RlLCBzZXRSZWplY3RJbnB1dE1vZGVdID0gdXNlU3RhdGUoZmFsc2UpXG4gIGNvbnN0IFtmb2N1c2VkVmFsdWUsIHNldEZvY3VzZWRWYWx1ZV0gPSB1c2VTdGF0ZTxUIHwgbnVsbD4obnVsbClcbiAgLy8gVHJhY2sgd2hldGhlciB1c2VyIGV2ZXIgZW50ZXJlZCBmZWVkYmFjayBtb2RlIChwZXJzaXN0cyBhZnRlciBjb2xsYXBzZSlcbiAgY29uc3QgW2FjY2VwdEZlZWRiYWNrTW9kZUVudGVyZWQsIHNldEFjY2VwdEZlZWRiYWNrTW9kZUVudGVyZWRdID1cbiAgICB1c2VTdGF0ZShmYWxzZSlcbiAgY29uc3QgW3JlamVjdEZlZWRiYWNrTW9kZUVudGVyZWQsIHNldFJlamVjdEZlZWRiYWNrTW9kZUVudGVyZWRdID1cbiAgICB1c2VTdGF0ZShmYWxzZSlcblxuICAvLyBGaW5kIHdoaWNoIG9wdGlvbiBpcyBmb2N1c2VkIGFuZCB3aGV0aGVyIGl0IGhhcyBmZWVkYmFjayBjb25maWdcbiAgY29uc3QgZm9jdXNlZE9wdGlvbiA9IG9wdGlvbnMuZmluZChvcHQgPT4gb3B0LnZhbHVlID09PSBmb2N1c2VkVmFsdWUpXG4gIGNvbnN0IGZvY3VzZWRGZWVkYmFja1R5cGUgPSBmb2N1c2VkT3B0aW9uPy5mZWVkYmFja0NvbmZpZz8udHlwZVxuXG4gIC8vIFNob3cgVGFiIGhpbnQgd2hlbiBmb2N1c2VkIG9uIGEgZmVlZGJhY2stZW5hYmxlZCBvcHRpb24gdGhhdCdzIG5vdCBhbHJlYWR5IGluIGlucHV0IG1vZGVcbiAgY29uc3Qgc2hvd1RhYkhpbnQgPVxuICAgIChmb2N1c2VkRmVlZGJhY2tUeXBlID09PSAnYWNjZXB0JyAmJiAhYWNjZXB0SW5wdXRNb2RlKSB8fFxuICAgIChmb2N1c2VkRmVlZGJhY2tUeXBlID09PSAncmVqZWN0JyAmJiAhcmVqZWN0SW5wdXRNb2RlKVxuXG4gIC8vIFRyYW5zZm9ybSBvcHRpb25zIHRvIFNlbGVjdC1jb21wYXRpYmxlIGZvcm1hdFxuICBjb25zdCBzZWxlY3RPcHRpb25zID0gdXNlTWVtbygoKTogT3B0aW9uV2l0aERlc2NyaXB0aW9uPFQ+W10gPT4ge1xuICAgIHJldHVybiBvcHRpb25zLm1hcChvcHQgPT4ge1xuICAgICAgY29uc3QgeyB2YWx1ZSwgbGFiZWwsIGZlZWRiYWNrQ29uZmlnIH0gPSBvcHRcblxuICAgICAgLy8gTm8gZmVlZGJhY2sgY29uZmlnID0gc2ltcGxlIG9wdGlvblxuICAgICAgaWYgKCFmZWVkYmFja0NvbmZpZykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGxhYmVsLFxuICAgICAgICAgIHZhbHVlLFxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHsgdHlwZSwgcGxhY2Vob2xkZXIgfSA9IGZlZWRiYWNrQ29uZmlnXG4gICAgICBjb25zdCBpc0lucHV0TW9kZSA9IHR5cGUgPT09ICdhY2NlcHQnID8gYWNjZXB0SW5wdXRNb2RlIDogcmVqZWN0SW5wdXRNb2RlXG4gICAgICBjb25zdCBvbkNoYW5nZSA9IHR5cGUgPT09ICdhY2NlcHQnID8gc2V0QWNjZXB0RmVlZGJhY2sgOiBzZXRSZWplY3RGZWVkYmFja1xuICAgICAgY29uc3QgZGVmYXVsdFBsYWNlaG9sZGVyID0gREVGQVVMVF9QTEFDRUhPTERFUlNbdHlwZV1cblxuICAgICAgLy8gV2hlbiBpbiBpbnB1dCBtb2RlLCBzaG93IGlucHV0IGZpZWxkXG4gICAgICBpZiAoaXNJbnB1dE1vZGUpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB0eXBlOiAnaW5wdXQnIGFzIGNvbnN0LFxuICAgICAgICAgIGxhYmVsLFxuICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgIHBsYWNlaG9sZGVyOiBwbGFjZWhvbGRlciA/PyBkZWZhdWx0UGxhY2Vob2xkZXIsXG4gICAgICAgICAgb25DaGFuZ2UsXG4gICAgICAgICAgYWxsb3dFbXB0eVN1Ym1pdFRvQ2FuY2VsOiB0cnVlLFxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIE5vdCBpbiBpbnB1dCBtb2RlIC0gc2hvdyBzaW1wbGUgb3B0aW9uXG4gICAgICByZXR1cm4ge1xuICAgICAgICBsYWJlbCxcbiAgICAgICAgdmFsdWUsXG4gICAgICB9XG4gICAgfSlcbiAgfSwgW29wdGlvbnMsIGFjY2VwdElucHV0TW9kZSwgcmVqZWN0SW5wdXRNb2RlXSlcblxuICAvLyBIYW5kbGUgVGFiIGtleSB0byB0b2dnbGUgaW5wdXQgbW9kZVxuICBjb25zdCBoYW5kbGVJbnB1dE1vZGVUb2dnbGUgPSB1c2VDYWxsYmFjayhcbiAgICAodmFsdWU6IFQpID0+IHtcbiAgICAgIGNvbnN0IG9wdGlvbiA9IG9wdGlvbnMuZmluZChvcHQgPT4gb3B0LnZhbHVlID09PSB2YWx1ZSlcbiAgICAgIGlmICghb3B0aW9uPy5mZWVkYmFja0NvbmZpZykgcmV0dXJuXG5cbiAgICAgIGNvbnN0IHsgdHlwZSB9ID0gb3B0aW9uLmZlZWRiYWNrQ29uZmlnXG4gICAgICBjb25zdCBhbmFseXRpY3NQcm9wcyA9IHtcbiAgICAgICAgdG9vbE5hbWU6XG4gICAgICAgICAgdG9vbEFuYWx5dGljc0NvbnRleHQ/LnRvb2xOYW1lIGFzIEFuYWx5dGljc01ldGFkYXRhX0lfVkVSSUZJRURfVEhJU19JU19OT1RfQ09ERV9PUl9GSUxFUEFUSFMsXG4gICAgICAgIGlzTWNwOiB0b29sQW5hbHl0aWNzQ29udGV4dD8uaXNNY3AgPz8gZmFsc2UsXG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlID09PSAnYWNjZXB0Jykge1xuICAgICAgICBpZiAoYWNjZXB0SW5wdXRNb2RlKSB7XG4gICAgICAgICAgc2V0QWNjZXB0SW5wdXRNb2RlKGZhbHNlKVxuICAgICAgICAgIGxvZ0V2ZW50KCd0ZW5ndV9hY2NlcHRfZmVlZGJhY2tfbW9kZV9jb2xsYXBzZWQnLCBhbmFseXRpY3NQcm9wcylcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzZXRBY2NlcHRJbnB1dE1vZGUodHJ1ZSlcbiAgICAgICAgICBzZXRBY2NlcHRGZWVkYmFja01vZGVFbnRlcmVkKHRydWUpXG4gICAgICAgICAgbG9nRXZlbnQoJ3Rlbmd1X2FjY2VwdF9mZWVkYmFja19tb2RlX2VudGVyZWQnLCBhbmFseXRpY3NQcm9wcylcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAncmVqZWN0Jykge1xuICAgICAgICBpZiAocmVqZWN0SW5wdXRNb2RlKSB7XG4gICAgICAgICAgc2V0UmVqZWN0SW5wdXRNb2RlKGZhbHNlKVxuICAgICAgICAgIGxvZ0V2ZW50KCd0ZW5ndV9yZWplY3RfZmVlZGJhY2tfbW9kZV9jb2xsYXBzZWQnLCBhbmFseXRpY3NQcm9wcylcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzZXRSZWplY3RJbnB1dE1vZGUodHJ1ZSlcbiAgICAgICAgICBzZXRSZWplY3RGZWVkYmFja01vZGVFbnRlcmVkKHRydWUpXG4gICAgICAgICAgbG9nRXZlbnQoJ3Rlbmd1X3JlamVjdF9mZWVkYmFja19tb2RlX2VudGVyZWQnLCBhbmFseXRpY3NQcm9wcylcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gICAgW29wdGlvbnMsIGFjY2VwdElucHV0TW9kZSwgcmVqZWN0SW5wdXRNb2RlLCB0b29sQW5hbHl0aWNzQ29udGV4dF0sXG4gIClcblxuICAvLyBIYW5kbGUgc2VsZWN0aW9uXG4gIGNvbnN0IGhhbmRsZVNlbGVjdCA9IHVzZUNhbGxiYWNrKFxuICAgICh2YWx1ZTogVCkgPT4ge1xuICAgICAgY29uc3Qgb3B0aW9uID0gb3B0aW9ucy5maW5kKG9wdCA9PiBvcHQudmFsdWUgPT09IHZhbHVlKVxuICAgICAgaWYgKCFvcHRpb24pIHJldHVyblxuXG4gICAgICAvLyBHZXQgZmVlZGJhY2sgaWYgYXBwbGljYWJsZVxuICAgICAgbGV0IGZlZWRiYWNrOiBzdHJpbmcgfCB1bmRlZmluZWRcbiAgICAgIGlmIChvcHRpb24uZmVlZGJhY2tDb25maWcpIHtcbiAgICAgICAgY29uc3QgcmF3RmVlZGJhY2sgPVxuICAgICAgICAgIG9wdGlvbi5mZWVkYmFja0NvbmZpZy50eXBlID09PSAnYWNjZXB0J1xuICAgICAgICAgICAgPyBhY2NlcHRGZWVkYmFja1xuICAgICAgICAgICAgOiByZWplY3RGZWVkYmFja1xuICAgICAgICBjb25zdCB0cmltbWVkRmVlZGJhY2sgPSByYXdGZWVkYmFjay50cmltKClcblxuICAgICAgICBpZiAodHJpbW1lZEZlZWRiYWNrKSB7XG4gICAgICAgICAgZmVlZGJhY2sgPSB0cmltbWVkRmVlZGJhY2tcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIExvZyBhY2NlcHQvcmVqZWN0IHN1Ym1pc3Npb24gd2l0aCBmZWVkYmFjayBjb250ZXh0XG4gICAgICAgIGNvbnN0IGFuYWx5dGljc1Byb3BzID0ge1xuICAgICAgICAgIHRvb2xOYW1lOlxuICAgICAgICAgICAgdG9vbEFuYWx5dGljc0NvbnRleHQ/LnRvb2xOYW1lIGFzIEFuYWx5dGljc01ldGFkYXRhX0lfVkVSSUZJRURfVEhJU19JU19OT1RfQ09ERV9PUl9GSUxFUEFUSFMsXG4gICAgICAgICAgaXNNY3A6IHRvb2xBbmFseXRpY3NDb250ZXh0Py5pc01jcCA/PyBmYWxzZSxcbiAgICAgICAgICBoYXNfaW5zdHJ1Y3Rpb25zOiAhIXRyaW1tZWRGZWVkYmFjayxcbiAgICAgICAgICBpbnN0cnVjdGlvbnNfbGVuZ3RoOiB0cmltbWVkRmVlZGJhY2s/Lmxlbmd0aCA/PyAwLFxuICAgICAgICAgIGVudGVyZWRfZmVlZGJhY2tfbW9kZTpcbiAgICAgICAgICAgIG9wdGlvbi5mZWVkYmFja0NvbmZpZy50eXBlID09PSAnYWNjZXB0J1xuICAgICAgICAgICAgICA/IGFjY2VwdEZlZWRiYWNrTW9kZUVudGVyZWRcbiAgICAgICAgICAgICAgOiByZWplY3RGZWVkYmFja01vZGVFbnRlcmVkLFxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG9wdGlvbi5mZWVkYmFja0NvbmZpZy50eXBlID09PSAnYWNjZXB0Jykge1xuICAgICAgICAgIGxvZ0V2ZW50KCd0ZW5ndV9hY2NlcHRfc3VibWl0dGVkJywgYW5hbHl0aWNzUHJvcHMpXG4gICAgICAgIH0gZWxzZSBpZiAob3B0aW9uLmZlZWRiYWNrQ29uZmlnLnR5cGUgPT09ICdyZWplY3QnKSB7XG4gICAgICAgICAgbG9nRXZlbnQoJ3Rlbmd1X3JlamVjdF9zdWJtaXR0ZWQnLCBhbmFseXRpY3NQcm9wcylcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBvblNlbGVjdCh2YWx1ZSwgZmVlZGJhY2spXG4gICAgfSxcbiAgICBbXG4gICAgICBvcHRpb25zLFxuICAgICAgYWNjZXB0RmVlZGJhY2ssXG4gICAgICByZWplY3RGZWVkYmFjayxcbiAgICAgIG9uU2VsZWN0LFxuICAgICAgdG9vbEFuYWx5dGljc0NvbnRleHQsXG4gICAgICBhY2NlcHRGZWVkYmFja01vZGVFbnRlcmVkLFxuICAgICAgcmVqZWN0RmVlZGJhY2tNb2RlRW50ZXJlZCxcbiAgICBdLFxuICApXG5cbiAgLy8gUmVnaXN0ZXIga2V5YmluZGluZyBoYW5kbGVycyBmb3Igb3B0aW9ucyB0aGF0IGhhdmUgYSBrZXliaW5kaW5nIHNldFxuICBjb25zdCBrZXliaW5kaW5nSGFuZGxlcnMgPSB1c2VNZW1vKCgpID0+IHtcbiAgICBjb25zdCBoYW5kbGVyczogUmVjb3JkPHN0cmluZywgKCkgPT4gdm9pZD4gPSB7fVxuICAgIGZvciAoY29uc3Qgb3B0IG9mIG9wdGlvbnMpIHtcbiAgICAgIGlmIChvcHQua2V5YmluZGluZykge1xuICAgICAgICBoYW5kbGVyc1tvcHQua2V5YmluZGluZ10gPSAoKSA9PiBoYW5kbGVTZWxlY3Qob3B0LnZhbHVlKVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaGFuZGxlcnNcbiAgfSwgW29wdGlvbnMsIGhhbmRsZVNlbGVjdF0pXG5cbiAgdXNlS2V5YmluZGluZ3Moa2V5YmluZGluZ0hhbmRsZXJzLCB7IGNvbnRleHQ6ICdDb25maXJtYXRpb24nIH0pXG5cbiAgLy8gSGFuZGxlIGNhbmNlbCAoRXNjKVxuICBjb25zdCBoYW5kbGVDYW5jZWwgPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgbG9nRXZlbnQoJ3Rlbmd1X3Blcm1pc3Npb25fcmVxdWVzdF9lc2NhcGUnLCB7fSlcbiAgICAvLyBJbmNyZW1lbnQgZXNjYXBlIGNvdW50IGZvciBhdHRyaWJ1dGlvbiB0cmFja2luZ1xuICAgIHNldEFwcFN0YXRlKHByZXYgPT4gKHtcbiAgICAgIC4uLnByZXYsXG4gICAgICBhdHRyaWJ1dGlvbjoge1xuICAgICAgICAuLi5wcmV2LmF0dHJpYnV0aW9uLFxuICAgICAgICBlc2NhcGVDb3VudDogcHJldi5hdHRyaWJ1dGlvbi5lc2NhcGVDb3VudCArIDEsXG4gICAgICB9LFxuICAgIH0pKVxuICAgIG9uQ2FuY2VsPy4oKVxuICB9LCBbb25DYW5jZWwsIHNldEFwcFN0YXRlXSlcblxuICByZXR1cm4gKFxuICAgIDxCb3ggZmxleERpcmVjdGlvbj1cImNvbHVtblwiPlxuICAgICAge3R5cGVvZiBxdWVzdGlvbiA9PT0gJ3N0cmluZycgPyA8VGV4dD57cXVlc3Rpb259PC9UZXh0PiA6IHF1ZXN0aW9ufVxuICAgICAgPFNlbGVjdFxuICAgICAgICBvcHRpb25zPXtzZWxlY3RPcHRpb25zfVxuICAgICAgICBpbmxpbmVEZXNjcmlwdGlvbnNcbiAgICAgICAgb25DaGFuZ2U9e2hhbmRsZVNlbGVjdH1cbiAgICAgICAgb25DYW5jZWw9e2hhbmRsZUNhbmNlbH1cbiAgICAgICAgb25Gb2N1cz17dmFsdWUgPT4ge1xuICAgICAgICAgIC8vIFJlc2V0IGlucHV0IG1vZGUgd2hlbiBuYXZpZ2F0aW5nIGF3YXksIGJ1dCBvbmx5IGlmIG5vIHRleHQgdHlwZWRcbiAgICAgICAgICBjb25zdCBuZXdPcHRpb24gPSBvcHRpb25zLmZpbmQob3B0ID0+IG9wdC52YWx1ZSA9PT0gdmFsdWUpXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgbmV3T3B0aW9uPy5mZWVkYmFja0NvbmZpZz8udHlwZSAhPT0gJ2FjY2VwdCcgJiZcbiAgICAgICAgICAgIGFjY2VwdElucHV0TW9kZSAmJlxuICAgICAgICAgICAgIWFjY2VwdEZlZWRiYWNrLnRyaW0oKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgc2V0QWNjZXB0SW5wdXRNb2RlKGZhbHNlKVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBuZXdPcHRpb24/LmZlZWRiYWNrQ29uZmlnPy50eXBlICE9PSAncmVqZWN0JyAmJlxuICAgICAgICAgICAgcmVqZWN0SW5wdXRNb2RlICYmXG4gICAgICAgICAgICAhcmVqZWN0RmVlZGJhY2sudHJpbSgpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBzZXRSZWplY3RJbnB1dE1vZGUoZmFsc2UpXG4gICAgICAgICAgfVxuICAgICAgICAgIHNldEZvY3VzZWRWYWx1ZSh2YWx1ZSlcbiAgICAgICAgfX1cbiAgICAgICAgb25JbnB1dE1vZGVUb2dnbGU9e2hhbmRsZUlucHV0TW9kZVRvZ2dsZX1cbiAgICAgIC8+XG4gICAgICA8Qm94IG1hcmdpblRvcD17MX0+XG4gICAgICAgIDxUZXh0IGRpbUNvbG9yPkVzYyB0byBjYW5jZWx7c2hvd1RhYkhpbnQgJiYgJyDCtyBUYWIgdG8gYW1lbmQnfTwvVGV4dD5cbiAgICAgIDwvQm94PlxuICAgIDwvQm94PlxuICApXG59XG4iXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPQSxLQUFLLElBQUksS0FBS0MsU0FBUyxFQUFFQyxXQUFXLEVBQUVDLE9BQU8sRUFBRUMsUUFBUSxRQUFRLE9BQU87QUFDN0UsU0FBU0MsR0FBRyxFQUFFQyxJQUFJLFFBQVEsY0FBYztBQUN4QyxjQUFjQyxnQkFBZ0IsUUFBUSw0QkFBNEI7QUFDbEUsU0FBU0MsY0FBYyxRQUFRLG9DQUFvQztBQUNuRSxTQUNFLEtBQUtDLDBEQUEwRCxF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