@camera.ui/server 2.2.7 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +8 -1
- package/dist/interface/assets/404-C0X5UBF4.js +1 -0
- package/dist/interface/assets/About-Ctp_u5qK.js +1 -0
- package/dist/interface/assets/Assistant-Bj2bAUHD.css +1 -0
- package/dist/interface/assets/Assistant-CDrBV_mg.js +1 -0
- package/dist/interface/assets/Automation-Dp6V80Iz.js +3 -0
- package/dist/interface/assets/Automation-R5o9sXYY.css +1 -0
- package/dist/interface/assets/AutomationImport-DKgg7atE.js +2 -0
- package/dist/interface/assets/AutomationStore-CU-m5VC8.js +2 -0
- package/dist/interface/assets/AutomationStoreDetail-CiyIs8Iu.js +2 -0
- package/dist/interface/assets/Automations-Dljh-sWu.js +2 -0
- package/dist/interface/assets/Camera-0p0P_mbp.css +1 -0
- package/dist/interface/assets/Camera-Bvovab-8.js +2 -0
- package/dist/interface/assets/CameraConsole-D_Fv-MAi.js +7 -0
- package/dist/interface/assets/Cameras-Cq7Gw-fk.js +651 -0
- package/dist/interface/assets/Camview-Bs2VvmUS.css +1 -0
- package/dist/interface/assets/Camview-CP6PA20C.js +1 -0
- package/dist/interface/assets/CertificateUpload-DjzNMFc3.js +1 -0
- package/dist/interface/assets/Config-Dl2TlyFe.js +2 -0
- package/dist/interface/assets/ConfigActionAssistant-DCkJ_Iqq.js +1 -0
- package/dist/interface/assets/ConfigActionCameraControl-2pzl59gR.js +1 -0
- package/dist/interface/assets/ConfigActionDelay-BAp1dr0N.js +1 -0
- package/dist/interface/assets/ConfigActionHttp-_kqgEuun.js +1 -0
- package/dist/interface/assets/ConfigActionImageInput-BgtACnCm.js +1 -0
- package/dist/interface/assets/ConfigActionMqtt-z7UzccW5.js +1 -0
- package/dist/interface/assets/ConfigActionNotification-bhbb5AqU.js +1 -0
- package/dist/interface/assets/ConfigActionNotificationControl-BbvX8MFu.js +1 -0
- package/dist/interface/assets/ConfigActionOutput-DdgSg3FU.js +1 -0
- package/dist/interface/assets/ConfigActionPlugin-DGjZd1L0.js +1 -0
- package/dist/interface/assets/ConfigActionSensor-DmImWFAo.js +1 -0
- package/dist/interface/assets/ConfigActionSnapshot-hVHSfdtS.js +1 -0
- package/dist/interface/assets/ConfigActionVariable-BIpruwsx.js +1 -0
- package/dist/interface/assets/ConfigConditionIfElse-DRSpsoR4.js +1 -0
- package/dist/interface/assets/ConfigConditionSensorState-C2SNARH7.js +1 -0
- package/dist/interface/assets/ConfigConditionSwitch-4SbQcU7N.js +1 -0
- package/dist/interface/assets/ConfigConditionTime-ESX3shbg.js +1 -0
- package/dist/interface/assets/ConfigSensorValueInput-CTUdAA-R.js +1 -0
- package/dist/interface/assets/ConfigTriggerDetection-BRr6ixxQ.js +1 -0
- package/dist/interface/assets/ConfigTriggerGeofence-D-xRMGrT.js +1 -0
- package/dist/interface/assets/ConfigTriggerManual-aXD6k1qa.js +1 -0
- package/dist/interface/assets/ConfigTriggerMqtt-pjHW4yOL.js +1 -0
- package/dist/interface/assets/ConfigTriggerSchedule-CYOt57qg.js +1 -0
- package/dist/interface/assets/ConfigTriggerSensor-BwJ_cAqd.js +1 -0
- package/dist/interface/assets/ConfigTriggerSystem-DBXIrjzU.js +1 -0
- package/dist/interface/assets/ConfigTriggerWebhook-CccBmMCb.js +1 -0
- package/dist/interface/assets/Console-DWAaz1C6.js +1 -0
- package/dist/interface/assets/CuiAssistantConversation-B3xEiNNt.js +5 -0
- package/dist/interface/assets/CuiAssistantConversation-C5ca1lgX.css +1 -0
- package/dist/interface/assets/CuiAutomationRunsDialog-CfylVPLI.js +1 -0
- package/dist/interface/assets/CuiBottomSheet-ACN23VLS.js +1 -0
- package/dist/interface/assets/CuiBottomSheet-DEVNeDqa.js +1 -0
- package/dist/interface/assets/CuiCameraPipCard-TYTCfwXf.css +1 -0
- package/dist/interface/assets/CuiCameraPipCard-rR_FW9zq.js +1 -0
- package/dist/interface/assets/CuiCameraRecordings-CnorhPhf.js +1 -0
- package/dist/interface/assets/CuiCameraShares-BxUgedC_.js +1 -0
- package/dist/interface/assets/CuiCameraTable-C3GB4Q2y.js +2 -0
- package/dist/interface/assets/CuiCameraTable-MHfnZSyK.js +1 -0
- package/dist/interface/assets/CuiChartTable-TAzZgetO.js +1 -0
- package/dist/interface/assets/CuiConsole-Cf5lOCE1.js +5 -0
- package/dist/interface/assets/CuiDataTable-DfjXa0C1.js +1 -0
- package/dist/interface/assets/CuiLightControl-ChK-SvJp.js +1 -0
- package/dist/interface/assets/CuiList-C4fxd9lD.js +1 -0
- package/dist/interface/assets/CuiMarkdownContent-Do04YgHe.js +1 -0
- package/dist/interface/assets/CuiMarkdownContent-qOPm3VEi.js +1 -0
- package/dist/interface/assets/CuiPluginCard-DMpANIQj.js +2 -0
- package/dist/interface/assets/CuiPluginCategoryChip-BKxJMid7.js +1 -0
- package/dist/interface/assets/CuiPluginOAuthButton-DnQ838JJ.js +2 -0
- package/dist/interface/assets/CuiPluginTrustBadge-DyYDUWV6.js +1 -0
- package/dist/interface/assets/CuiQRCode-S9fPi0_l.js +1 -0
- package/dist/interface/assets/CuiSchema-DScmDQsh.js +1 -0
- package/dist/interface/assets/CuiTopNavbarItem-CT10aAlO.js +1 -0
- package/dist/interface/assets/Faces-Coy-tUVM.js +1 -0
- package/dist/interface/assets/FirstSteps-CrMJC049.js +1 -0
- package/dist/interface/assets/Floorplan-Bj_mVrxp.js +1 -0
- package/dist/interface/assets/Floorplan-CT5TrMSD.css +1 -0
- package/dist/interface/assets/Instances-B_mpKAng.js +1 -0
- package/dist/interface/assets/Logs-fY1dpQk4.js +6 -0
- package/dist/interface/assets/Menu-Bgi-NLdg.js +1 -0
- package/dist/interface/assets/Metrics-DnMeIrkf.css +1 -0
- package/dist/interface/assets/Metrics-k9KACiwh.js +12 -0
- package/dist/interface/assets/OAuthDeviceFlow-xTh83xmc.js +1 -0
- package/dist/interface/assets/Plugin-BB7x7UHw.css +1 -0
- package/dist/interface/assets/Plugin-VWq7sONB.js +1 -0
- package/dist/interface/assets/PluginConsole-LnnDOVBL.js +7 -0
- package/dist/interface/assets/PluginDetail-CKD9sbDx.js +2 -0
- package/dist/interface/assets/PluginSchema-BnB0_6Sk.js +1 -0
- package/dist/interface/assets/PluginSearch-BoBZLLbr.js +1 -0
- package/dist/interface/assets/PluginSearch-kGhweU1J.js +2 -0
- package/dist/interface/assets/PluginUpdateProgress-DMx0QlgE.js +1 -0
- package/dist/interface/assets/Plugins-Ekmr6aVa.js +1 -0
- package/dist/interface/assets/RecentEventsFilter-StLJNuks.js +1 -0
- package/dist/interface/assets/Recordings-8PqxJOI3.css +1 -0
- package/dist/interface/assets/Recordings-Bvkuk_TV.js +1 -0
- package/dist/interface/assets/SensorEdit-CAf9Nb01.js +1 -0
- package/dist/interface/assets/SensorHistory-il8bDErX.js +1 -0
- package/dist/interface/assets/Sensors-sxQ6HLKo.js +2 -0
- package/dist/interface/assets/Settings-Bu0G7Ebx.js +1 -0
- package/dist/interface/assets/Settings-DtCSaLPb.css +1 -0
- package/dist/interface/assets/SettingsAccount-8OZJLQi-.js +1 -0
- package/dist/interface/assets/SettingsAccount-bSfFi9YH.js +1 -0
- package/dist/interface/assets/SettingsAppearance-CnvN_Tzr.js +1 -0
- package/dist/interface/assets/SettingsAppearance-EvPWgF4c.js +1 -0
- package/dist/interface/assets/SettingsAssistant-B6s6pHCx.js +1 -0
- package/dist/interface/assets/SettingsBackup-Dd2FaUcN.js +1 -0
- package/dist/interface/assets/SettingsList-SvCO_gfG.js +1 -0
- package/dist/interface/assets/SettingsMqtt-BXBzHX84.js +1 -0
- package/dist/interface/assets/SettingsNotifications-CV-jJwFV.js +1 -0
- package/dist/interface/assets/SettingsPermissions-GchFaWjz.js +1 -0
- package/dist/interface/assets/SettingsRecordings-C4Ch_jmV.js +1 -0
- package/dist/interface/assets/SettingsRemote-CsIGx-LU.css +1 -0
- package/dist/interface/assets/SettingsRemote-OZHDJKSq.js +2 -0
- package/dist/interface/assets/SettingsSystem-BJlHXwVs.js +2 -0
- package/dist/interface/assets/SettingsUsers-RGOkOzx0.js +1 -0
- package/dist/interface/assets/Terminal-DX-ECC91.js +4 -0
- package/dist/interface/assets/Training-B8my7vka.js +1 -0
- package/dist/interface/assets/Training-D1DDjCCD.css +1 -0
- package/dist/interface/assets/Updates-DmavyhAn.js +2 -0
- package/dist/interface/assets/VariableInput-DQJle67Y.js +1 -0
- package/dist/interface/assets/VariableSuggestions-D8V739dF.js +1 -0
- package/dist/interface/assets/VersionsHandler-B41TJhgY.js +7 -0
- package/dist/interface/assets/VirtualSensorCreate-MfLh-LpH.js +1 -0
- package/dist/interface/assets/Workers-CafDeRhH.js +2 -0
- package/dist/interface/assets/Workers-Dey1snI4.css +1 -0
- package/dist/interface/assets/account-DjBQulDn.js +1 -0
- package/dist/interface/assets/ace-BPAekgyf.js +1 -0
- package/dist/interface/assets/ace.config-CvKE-yp1.js +1 -0
- package/dist/interface/assets/alert-circle-B-JCMbb9.js +1 -0
- package/dist/interface/assets/alert-outline-B4ZZowEj.js +1 -0
- package/dist/interface/assets/api-By0v6EeA.css +2 -0
- package/dist/interface/assets/api-D1iULsSy.js +4 -0
- package/dist/interface/assets/api-DbUdfXO_.js +1 -0
- package/dist/interface/assets/arrow-left-PeaVwpHd.js +1 -0
- package/dist/interface/assets/assistant-7hqP6OpA.js +1 -0
- package/dist/interface/assets/assistantModels-D3ncWWu0.js +1 -0
- package/dist/interface/assets/auth-CDxrn7fe.js +1 -0
- package/dist/interface/assets/automations-CTTQlGCW.js +1 -0
- package/dist/interface/assets/back-filled-CJoz7Gkl.js +1 -0
- package/dist/interface/assets/bell-ring-CBf0Yn3H.js +1 -0
- package/dist/interface/assets/brain-uZ03n3LW.js +1 -0
- package/dist/interface/assets/cameraSources-MOiE_1-W.js +1 -0
- package/dist/interface/assets/cctv-VgKQ-dBV.js +1 -0
- package/dist/interface/assets/check-circle-BU-KNgPB.js +1 -0
- package/dist/interface/assets/check-circle-outline-BsxzAMed.js +1 -0
- package/dist/interface/assets/chevron-down-CxK4Sfjs.js +1 -0
- package/dist/interface/assets/chevron-up-DWfNH8va.js +1 -0
- package/dist/interface/assets/clock-outline-BtWx4GaF.js +1 -0
- package/dist/interface/assets/close-Be7oB7d_.js +1 -0
- package/dist/interface/assets/close-circle-D7Jmhp_7.js +1 -0
- package/dist/interface/assets/cloud-check-zCGJxpWI.js +1 -0
- package/dist/interface/assets/cloudHandoff-CJzFH7CW.js +1 -0
- package/dist/interface/assets/config-6EiGxiYm.js +1 -0
- package/dist/interface/assets/content-copy-BcYlfuFc.js +1 -0
- package/dist/interface/assets/copy-DuY-M96E.js +1 -0
- package/dist/interface/assets/cube-scan-Cae03i_N.js +1 -0
- package/dist/interface/assets/database-refresh-outline-B3OEQFF7.js +1 -0
- package/dist/interface/assets/delete-BWgOAzKl.js +1 -0
- package/dist/interface/assets/dist-DmpuuM9s.js +1 -0
- package/dist/interface/assets/dots-vertical-Kby1GY8_.js +1 -0
- package/dist/interface/assets/download-C291Yq7I.js +1 -0
- package/dist/interface/assets/esm-B2TVBF3B.js +1 -0
- package/dist/interface/assets/esm-BEntuCG7.js +1 -0
- package/dist/interface/assets/esm-BRnyrFH8.js +1 -0
- package/dist/interface/assets/esm-CCwXzd_8.js +1 -0
- package/dist/interface/assets/esm-CEjwTsuD.js +1 -0
- package/dist/interface/assets/esm-CGGV9tC4.js +1 -0
- package/dist/interface/assets/esm-CI2tTOc5.js +1 -0
- package/dist/interface/assets/esm-CgxZmMYv.js +1 -0
- package/dist/interface/assets/esm-Csc6f5Fy.js +1 -0
- package/dist/interface/assets/esm-Qzx3d-Ie.js +1 -0
- package/dist/interface/assets/esm-a_w7mTdx.js +1 -0
- package/dist/interface/assets/esm-iKfsu7-H.js +1 -0
- package/dist/interface/assets/esm-ks5kvk_e.js +1 -0
- package/dist/interface/assets/esm-nJfTguKF.js +1 -0
- package/dist/interface/assets/eventLabels-idFWh3Y_.js +1 -0
- package/dist/interface/assets/eye-off-zGCIHKOK.js +1 -0
- package/dist/interface/assets/flowSchema-Dp_-p9WA.js +1 -0
- package/dist/interface/assets/help-circle-outline-DXFepDAG.js +1 -0
- package/dist/interface/assets/history-D-FlZdKD.js +1 -0
- package/dist/interface/assets/home-DPdzRxcM.js +1 -0
- package/dist/interface/assets/information-outline-ChOM9qgI.js +1 -0
- package/dist/interface/assets/intercomService-BQYzjnAi.js +1 -0
- package/dist/interface/assets/lan-DvYEO83l.js +1 -0
- package/dist/interface/assets/main-0oXl_8v7.js +3 -0
- package/dist/interface/assets/main-CdvAniEp.css +1 -0
- package/dist/interface/assets/microphone-D-T9xga4.js +1 -0
- package/dist/interface/assets/minus-4T4INuO4.js +1 -0
- package/dist/interface/assets/mqtt-ChvXxMhR.js +1 -0
- package/dist/interface/assets/native-CtfXrwj5.js +1 -0
- package/dist/interface/assets/native-JMtkOkIV.js +1 -0
- package/dist/interface/assets/nodeDefinitions-Dp8cnne1.js +1 -0
- package/dist/interface/assets/notifications-CbL-1oMs.js +1 -0
- package/dist/interface/assets/pause-DHqHYA3V.js +1 -0
- package/dist/interface/assets/pencil-outline-D-GmPf8M.js +1 -0
- package/dist/interface/assets/pencil-vACi-JzY.js +1 -0
- package/dist/interface/assets/plugin-Dt5Xetfz.js +1 -0
- package/dist/interface/assets/plugins-lsoAntRQ.js +1 -0
- package/dist/interface/assets/plus-BBUb8_uL.js +1 -0
- package/dist/interface/assets/plus-BJb7U4bN.js +1 -0
- package/dist/interface/assets/power-Dm_aNIz-.js +1 -0
- package/dist/interface/assets/radar-Dcvdz--e.js +1 -0
- package/dist/interface/assets/refresh-CO4F18Je.js +1 -0
- package/dist/interface/assets/restore-xRBt3Grb.js +1 -0
- package/dist/interface/assets/rooms-P8WrRIco.js +1 -0
- package/dist/interface/assets/round-alt-arrow-left-bold-CZHXzGS5.js +1 -0
- package/dist/interface/assets/search-D75YW08B.js +1 -0
- package/dist/interface/assets/sensorIcons-BRTtoaHX.js +1 -0
- package/dist/interface/assets/sensorSlots-BTj-IM7z.js +1 -0
- package/dist/interface/assets/sensors-Dxc7HgjZ.js +1 -0
- package/dist/interface/assets/server-DlK8gUoE.js +1 -0
- package/dist/interface/assets/settings-DDOgc5BX.js +1 -0
- package/dist/interface/assets/source-branch-DVHuYlkZ.js +1 -0
- package/dist/interface/assets/theme-BOppzzar.js +1 -0
- package/dist/interface/assets/trash-2-DDKPtl2x.js +1 -0
- package/dist/interface/assets/trash-can-outline-DVH3zgo0.js +1 -0
- package/dist/interface/assets/trash-fill-C_IJ4Vu2.js +1 -0
- package/dist/interface/assets/trash2-DY0XTaJD.js +1 -0
- package/dist/interface/assets/types-CeruGCb8.js +1 -0
- package/dist/interface/assets/types-J1Drrxo1.js +1 -0
- package/dist/interface/assets/types-U4AuTNLR.js +1 -0
- package/dist/interface/assets/undo-YRkBYCnf.js +1 -0
- package/dist/interface/assets/ungrouped-ING_JAuK.js +1 -0
- package/dist/interface/assets/updates-DtVp84Y0.js +1 -0
- package/dist/interface/assets/upload-2WcHRjTq.js +1 -0
- package/dist/interface/assets/upload-BiE7VzTj.js +1 -0
- package/dist/interface/assets/useAppVersion-BGgCk5GD.js +1 -0
- package/dist/interface/assets/useAssistantActions-C13O5EHU.js +1 -0
- package/dist/interface/assets/useBackupRestore-vrhmc9i-.js +1 -0
- package/dist/interface/assets/useCameraOptions-CI1baRmm.js +1 -0
- package/dist/interface/assets/useKeyboardInset-CvgJp091.js +1 -0
- package/dist/interface/assets/useLogsSocket-Bf0BI8ET.js +1 -0
- package/dist/interface/assets/useNavLayout-6zM1Y-7B.js +1 -0
- package/dist/interface/assets/usePermissions-DZitFsBQ.js +1 -0
- package/dist/interface/assets/usePluginUpdates-VZdpJ_Ax.js +1 -0
- package/dist/interface/assets/usePushRegistration-vcbMrTxZ.js +2 -0
- package/dist/interface/assets/useServerRestart-DrpuNbIu.js +1 -0
- package/dist/interface/assets/useStreamStatus-l3Pfk1H4.js +1 -0
- package/dist/interface/assets/useTabSwipe-BSpi25WV.js +1 -0
- package/dist/interface/assets/useUpdateChannel-kAl-5UNY.js +1 -0
- package/dist/interface/assets/useUpdatesSocket-CaFz_fEb.js +1 -0
- package/dist/interface/assets/useUserOptions-BKteXnmU.js +1 -0
- package/dist/interface/assets/variable-Cp8o-q8t.js +1 -0
- package/dist/interface/assets/vendor-Df81FCJz.js +29 -0
- package/dist/interface/assets/vendor-ace-QSsGUspX.js +1085 -0
- package/dist/interface/assets/vendor-cameraui-K1Nw4PvF.js +2326 -0
- package/dist/interface/assets/vendor-capacitor-t5EIN1GG.js +2 -0
- package/dist/interface/assets/vendor-chart-BiJYkx5_.js +3 -0
- package/dist/interface/assets/vendor-core-CJdfpB0I.js +1 -0
- package/dist/interface/assets/vendor-dnd-C1kMh9_t.js +2 -0
- package/dist/interface/assets/vendor-draggabilly-Cw1oJ6qc.js +1 -0
- package/dist/interface/assets/vendor-leaflet-OSZlONe5.js +1 -0
- package/dist/interface/assets/vendor-markdown-DTWiWKBj.js +14 -0
- package/dist/interface/assets/vendor-primevue-DoA2Rwcb.js +3942 -0
- package/dist/interface/assets/vendor-vueflow-DWU_IzGe.js +26 -0
- package/dist/interface/assets/walk-B8FNhXuj.js +1 -0
- package/dist/interface/assets/web-B98ahwoP.js +1 -0
- package/dist/interface/assets/web-BSsSrRZf.js +1 -0
- package/dist/interface/assets/web-BiNRDta4.js +1 -0
- package/dist/interface/assets/web-BjKL51lK-CZKmYhby.js +1 -0
- package/dist/interface/assets/web-BjtOcquy.js +1 -0
- package/dist/interface/assets/web-CkTE9nCG.js +1 -0
- package/dist/interface/assets/web-Cvogq5S5.js +1 -0
- package/dist/interface/assets/web-D-A4EBKj.js +1 -0
- package/dist/interface/assets/web-DVGMBduz.js +1 -0
- package/dist/interface/assets/web-SpWB7I6X.js +1 -0
- package/dist/interface/assets/web-k0ihT_qK.js +1 -0
- package/dist/interface/assets/web-ovBpm7Dl.js +1 -0
- package/dist/interface/assets/web-z5Xz9tOQ.js +1 -0
- package/dist/interface/assets/web-zfhkFevT.js +1 -0
- package/dist/interface/assets/webhook-DIjChTrs.js +1 -0
- package/dist/interface/assets/workbox-window.prod.es5-DRKojI0e.js +1 -0
- package/dist/interface/assets/zoom-in-rMB152Uz.js +1 -0
- package/dist/interface/ha/404-RtgPpD9N.js +60 -0
- package/dist/interface/ha/About-0PRv9bU0.js +55 -0
- package/dist/interface/ha/Assistant-DbwxVfpl.js +9853 -0
- package/dist/interface/ha/Automation-D3HomdH7.js +2029 -0
- package/dist/interface/ha/AutomationImport-nQUUvZcv.js +206 -0
- package/dist/interface/ha/AutomationStore-BXDD92wZ.js +336 -0
- package/dist/interface/ha/AutomationStoreDetail-BYeq7FID.js +122 -0
- package/dist/interface/ha/Automations-CJlGqmSP.js +424 -0
- package/dist/interface/ha/Camera-Ai4BxVh_.js +747 -0
- package/dist/interface/ha/CameraConsole-UMNOX3dE.js +52 -0
- package/dist/interface/ha/Cameras-BW-AEXYi.js +1971 -0
- package/dist/interface/ha/Camview-jikpVEE0.js +1336 -0
- package/dist/interface/ha/Config-BOxwBH2D.js +356 -0
- package/dist/interface/ha/ConfigActionAssistant--3iWk9sq.js +182 -0
- package/dist/interface/ha/ConfigActionCameraControl-DbVXWTeA.js +152 -0
- package/dist/interface/ha/ConfigActionHttp-Du3n2Yj0.js +134 -0
- package/dist/interface/ha/ConfigActionImageInput-BrJrTZTY.js +171 -0
- package/dist/interface/ha/ConfigActionMqtt-DZd1BNUt.js +81 -0
- package/dist/interface/ha/ConfigActionNotification-CJWW10gt.js +199 -0
- package/dist/interface/ha/ConfigActionNotificationControl-Bl41AVv1.js +111 -0
- package/dist/interface/ha/ConfigActionOutput-OTj7Lwgq.js +98 -0
- package/dist/interface/ha/ConfigActionPlugin-B790PEk0.js +172 -0
- package/dist/interface/ha/ConfigActionSensor-BG3jZxge.js +139 -0
- package/dist/interface/ha/ConfigActionSnapshot-fGmLl6jb.js +48 -0
- package/dist/interface/ha/ConfigActionVariable-CK3vYDsr.js +88 -0
- package/dist/interface/ha/ConfigConditionIfElse-DyFLGg3y.js +124 -0
- package/dist/interface/ha/ConfigConditionSensorState-BUTfeFO2.js +192 -0
- package/dist/interface/ha/ConfigConditionSwitch-iDG_ubif.js +128 -0
- package/dist/interface/ha/ConfigSensorValueInput-BmRIGUKB.js +170 -0
- package/dist/interface/ha/ConfigTriggerDetection-DyPQGt9M.js +241 -0
- package/dist/interface/ha/ConfigTriggerGeofence-CGE-bH_t.js +4888 -0
- package/dist/interface/ha/ConfigTriggerMqtt-CM3KZqBc.js +134 -0
- package/dist/interface/ha/ConfigTriggerSensor-DoHMcwP4.js +73 -0
- package/dist/interface/ha/ConfigTriggerSystem-BYKbW4Zr.js +192 -0
- package/dist/interface/ha/ConfigTriggerWebhook-5PBAadG8.js +94 -0
- package/dist/interface/ha/Console-BEXzl4p1.js +348 -0
- package/dist/interface/ha/CuiAutomationRunsDialog-DkK_ar5G.js +130 -0
- package/dist/interface/ha/CuiBottomSheet-CYNvQV4T.js +270 -0
- package/dist/interface/ha/CuiCameraRecordings-DYjecmE_.js +533 -0
- package/dist/interface/ha/CuiCameraShares-C0H60nZS.js +121 -0
- package/dist/interface/ha/CuiCameraTable-CQNMyBaq.js +169 -0
- package/dist/interface/ha/CuiChartTable-Bhv1p9zj.js +6801 -0
- package/dist/interface/ha/CuiConsole-DtXorGF5.js +244 -0
- package/dist/interface/ha/CuiDataTable-Cy8EjCk9.js +8732 -0
- package/dist/interface/ha/CuiList-DnW6Q5m2.js +57 -0
- package/dist/interface/ha/CuiPluginCard-B4SCUblV.js +769 -0
- package/dist/interface/ha/CuiPluginOAuthButton-BKg9SftQ.js +79 -0
- package/dist/interface/ha/CuiPluginTrustBadge-CEtUJhCJ.js +123 -0
- package/dist/interface/ha/CuiQRCode-gp-9hqyk.js +86 -0
- package/dist/interface/ha/CuiSchema-CYpr_dD7.js +963 -0
- package/dist/interface/ha/CuiTopNavbarItem-CM-1oPxf.js +140 -0
- package/dist/interface/ha/Faces-pa60ySng.js +1575 -0
- package/dist/interface/ha/FirstSteps-D42yZm7R.js +251 -0
- package/dist/interface/ha/Floorplan-BvE546pE.js +3657 -0
- package/dist/interface/ha/Instances-CAGCyfbB.js +680 -0
- package/dist/interface/ha/Logs-RB3Ba8WM.js +418 -0
- package/dist/interface/ha/Menu-hAnHu_jq.js +156 -0
- package/dist/interface/ha/Metrics-ChYTebkX.js +1448 -0
- package/dist/interface/ha/OAuthDeviceFlow-C05pH-9o.js +112 -0
- package/dist/interface/ha/Plugin-D7XwcXkW.js +1752 -0
- package/dist/interface/ha/PluginConsole-DphEIOlL.js +56 -0
- package/dist/interface/ha/PluginDetail-DfMl-yCl.js +805 -0
- package/dist/interface/ha/PluginSearch-BPN4Opg5.js +462 -0
- package/dist/interface/ha/PluginUpdateProgress-ByJ0R5sW.js +34 -0
- package/dist/interface/ha/Plugins-BhKmjjNn.js +692 -0
- package/dist/interface/ha/RecentEventsFilter-BkLMlGVJ.js +78 -0
- package/dist/interface/ha/Recordings-BaU7M1OW.js +1836 -0
- package/dist/interface/ha/SensorEdit-DWxcCJ0F.js +1462 -0
- package/dist/interface/ha/SensorHistory-DuA9E9wT.js +54 -0
- package/dist/interface/ha/Sensors-CVpIHcgG.js +1402 -0
- package/dist/interface/ha/Settings-BO2eBGEn.js +218 -0
- package/dist/interface/ha/SettingsAccount-BQZZfoSM.js +971 -0
- package/dist/interface/ha/SettingsAppearance-B_yGl89u.js +220 -0
- package/dist/interface/ha/SettingsAssistant-kMOixl9g.js +2025 -0
- package/dist/interface/ha/SettingsBackup-BpG-W4j-.js +556 -0
- package/dist/interface/ha/SettingsList-Btnkzu94.js +40 -0
- package/dist/interface/ha/SettingsMqtt-C4DX9cNC.js +526 -0
- package/dist/interface/ha/SettingsNotifications-DI6ImggH.js +529 -0
- package/dist/interface/ha/SettingsPermissions-BCDyCFcb.js +84 -0
- package/dist/interface/ha/SettingsRecordings-Bq5NkJhd.js +152 -0
- package/dist/interface/ha/SettingsRemote-CtncaPIA.js +1813 -0
- package/dist/interface/ha/SettingsSystem-BJXuA7xA.js +376 -0
- package/dist/interface/ha/SettingsUsers-BF0rDluv.js +379 -0
- package/dist/interface/ha/Terminal-kTCe2jP3.js +612 -0
- package/dist/interface/ha/Training-BM2Xb8Ef.js +1754 -0
- package/dist/interface/ha/Updates-Cv1EY_T0.js +343 -0
- package/dist/interface/ha/VariableInput-BO2zZu4N.js +52 -0
- package/dist/interface/ha/VersionsHandler-CRnT9-K7.js +216 -0
- package/dist/interface/ha/VirtualSensorCreate-6dVRxPjw.js +101 -0
- package/dist/interface/ha/Workers-MHia86lu.js +814 -0
- package/dist/interface/ha/ace-C9MtBQVV.js +13236 -0
- package/dist/interface/ha/ace.config-CSXnaIzV.js +1429 -0
- package/dist/interface/ha/api-CH_Y8Hee.js +65411 -0
- package/dist/interface/ha/api-DylRa66V.js +29 -0
- package/dist/interface/ha/assistant-smRQYA6p.js +349 -0
- package/dist/interface/ha/auth-BXj5Fm6s.js +271 -0
- package/dist/interface/ha/automationBlueprint-DGjftXFC.js +250 -0
- package/dist/interface/ha/cameraui-cards.js +1 -1
- package/dist/interface/ha/cards-E0zw1UVg.js +13477 -0
- package/dist/interface/ha/config-dG_DA6XL.js +116 -0
- package/dist/interface/ha/dist-BQf9ANPx.js +3257 -0
- package/dist/interface/ha/dist-euRmladF.js +287 -0
- package/dist/interface/ha/eventLabels-B5GrM5jO.js +734 -0
- package/dist/interface/ha/intercomService-BtJ_zUNd.js +1400 -0
- package/dist/interface/ha/mqtt-CP3vVkRJ.js +56 -0
- package/dist/interface/ha/notifications-CZNwSXTg.js +159 -0
- package/dist/interface/ha/pinia-CVnHHb-s.js +7696 -0
- package/dist/interface/ha/plugins--eatOIaI.js +592 -0
- package/dist/interface/ha/protocol-BB4jdtUC-BhEwymva.js +789 -0
- package/dist/interface/ha/rooms-D5E6K75d.js +45 -0
- package/dist/interface/ha/server-D1BqEY7i.js +239 -0
- package/dist/interface/ha/types-CWogEoya.js +1073 -0
- package/dist/interface/ha/ungrouped-Ch4UX4dy.js +58 -0
- package/dist/interface/ha/updates-B48Owi1w.js +341 -0
- package/dist/interface/ha/useAppVersion-D95sKTJR.js +22 -0
- package/dist/interface/ha/useAssistantActions-kDwiO-u5.js +29 -0
- package/dist/interface/ha/useKeyboardInset-C2R51vsC.js +27 -0
- package/dist/interface/ha/useLogsSocket-BzNWa2y2.js +59 -0
- package/dist/interface/ha/useNavLayout-228cwwqA.js +125 -0
- package/dist/interface/ha/usePermissions-CfA5x7Df.js +72 -0
- package/dist/interface/ha/useServerRestart-B0c40zs5.js +23 -0
- package/dist/interface/ha/useTabSwipe-CfZg5hWj.js +45 -0
- package/dist/interface/ha/useUpdateChannel-DQxI7FrD.js +22 -0
- package/dist/interface/ha/useUpdatesSocket-B8LqBBd3.js +34 -0
- package/dist/interface/ha/useUserOptions-dZf6ejlz.js +15 -0
- package/dist/interface/ha/walk-CsSXaeJw.js +33 -0
- package/dist/interface/index.html +71 -72
- package/dist/interface/sw.js +1 -1
- package/dist/interface/workbox-5f52ac45.js +1 -0
- package/dist/server/package.json +23 -23
- package/dist/server/requirements.txt +2 -2
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/__init__.py +22 -0
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/camera/config.py +12 -0
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/camera/device.py +5 -1
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/internal/camera_config_internal.py +5 -1
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/manager/__init__.py +2 -1
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/plugin/__init__.py +10 -0
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/plugin/contract.py +6 -0
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/plugin/interfaces.py +92 -4
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/__init__.py +16 -0
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/base.py +4 -0
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/face_embedder.py +1 -1
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/object.py +3 -3
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/person_embedder.py +65 -0
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/segmenter.py +81 -0
- package/dist/server/src/api/controllers/plugins.controller.js +1 -0
- package/dist/server/src/api/controllers/plugins.controller.js.map +1 -1
- package/dist/server/src/api/controllers/workers.controller.d.ts +2 -2
- package/dist/server/src/api/controllers/workers.controller.js +8 -2
- package/dist/server/src/api/controllers/workers.controller.js.map +1 -1
- package/dist/server/src/api/database/index.d.ts +2 -1
- package/dist/server/src/api/database/index.js +31 -7
- package/dist/server/src/api/database/index.js.map +1 -1
- package/dist/server/src/api/database/migrations/v2-2-9.d.ts +3 -0
- package/dist/server/src/api/database/migrations/v2-2-9.js +28 -0
- package/dist/server/src/api/database/migrations/v2-2-9.js.map +1 -0
- package/dist/server/src/api/database/record-schemas.d.ts +4 -1
- package/dist/server/src/api/database/record-schemas.js +1 -0
- package/dist/server/src/api/database/record-schemas.js.map +1 -1
- package/dist/server/src/api/database/types.d.ts +21 -1
- package/dist/server/src/api/routes/workers.routes.js +4 -4
- package/dist/server/src/api/routes/workers.routes.js.map +1 -1
- package/dist/server/src/api/schemas/assistant.schema.d.ts +1 -1
- package/dist/server/src/api/schemas/cameras.schema.d.ts +178 -76
- package/dist/server/src/api/schemas/cameras.schema.js +26 -2
- package/dist/server/src/api/schemas/cameras.schema.js.map +1 -1
- package/dist/server/src/api/schemas/training.schema.d.ts +15 -3
- package/dist/server/src/api/schemas/training.schema.js +4 -1
- package/dist/server/src/api/schemas/training.schema.js.map +1 -1
- package/dist/server/src/api/schemas/users.schema.d.ts +12 -0
- package/dist/server/src/api/schemas/users.schema.js +4 -0
- package/dist/server/src/api/schemas/users.schema.js.map +1 -1
- package/dist/server/src/api/schemas/workers.schema.d.ts +5 -4
- package/dist/server/src/api/schemas/workers.schema.js +6 -3
- package/dist/server/src/api/schemas/workers.schema.js.map +1 -1
- package/dist/server/src/api/services/cameras.service.d.ts +3 -0
- package/dist/server/src/api/services/cameras.service.js +47 -2
- package/dist/server/src/api/services/cameras.service.js.map +1 -1
- package/dist/server/src/api/services/plugins.service.d.ts +1 -0
- package/dist/server/src/api/services/plugins.service.js +5 -1
- package/dist/server/src/api/services/plugins.service.js.map +1 -1
- package/dist/server/src/api/services/workers.service.d.ts +2 -0
- package/dist/server/src/api/services/workers.service.js +15 -0
- package/dist/server/src/api/services/workers.service.js.map +1 -1
- package/dist/server/src/api/types/index.d.ts +3 -2
- package/dist/server/src/api/websocket/nsp/worker-perf.js +2 -0
- package/dist/server/src/api/websocket/nsp/worker-perf.js.map +1 -1
- package/dist/server/src/api/websocket/types.d.ts +1 -0
- package/dist/server/src/assistant/pricing.js +39 -10
- package/dist/server/src/assistant/pricing.js.map +1 -1
- package/dist/server/src/assistant/providers.js +9 -1
- package/dist/server/src/assistant/providers.js.map +1 -1
- package/dist/server/src/assistant/search.d.ts +17 -0
- package/dist/server/src/assistant/search.js +10 -2
- package/dist/server/src/assistant/search.js.map +1 -1
- package/dist/server/src/assistant/tools/plugins.js +7 -3
- package/dist/server/src/assistant/tools/plugins.js.map +1 -1
- package/dist/server/src/assistant/types.d.ts +2 -0
- package/dist/server/src/automations/actions/plugin.js +5 -9
- package/dist/server/src/automations/actions/plugin.js.map +1 -1
- package/dist/server/src/automations/pluginMethodRegistry.d.ts +6 -0
- package/dist/server/src/automations/pluginMethodRegistry.js +39 -0
- package/dist/server/src/automations/pluginMethodRegistry.js.map +1 -1
- package/dist/server/src/automations/segment-picture.d.ts +16 -0
- package/dist/server/src/automations/segment-picture.js +152 -0
- package/dist/server/src/automations/segment-picture.js.map +1 -0
- package/dist/server/src/camera/decoder/detection-coordinator.d.ts +5 -2
- package/dist/server/src/camera/decoder/detection-coordinator.js +45 -22
- package/dist/server/src/camera/decoder/detection-coordinator.js.map +1 -1
- package/dist/server/src/camera/decoder/detection-pipeline.d.ts +30 -2
- package/dist/server/src/camera/decoder/detection-pipeline.js +81 -21
- package/dist/server/src/camera/decoder/detection-pipeline.js.map +1 -1
- package/dist/server/src/camera/decoder/event-manager.d.ts +13 -4
- package/dist/server/src/camera/decoder/event-manager.js +108 -128
- package/dist/server/src/camera/decoder/event-manager.js.map +1 -1
- package/dist/server/src/camera/decoder/event-trace.d.ts +41 -1
- package/dist/server/src/camera/decoder/event-trace.js +63 -8
- package/dist/server/src/camera/decoder/event-trace.js.map +1 -1
- package/dist/server/src/camera/decoder/face-tracks.d.ts +26 -0
- package/dist/server/src/camera/decoder/face-tracks.js +199 -0
- package/dist/server/src/camera/decoder/face-tracks.js.map +1 -0
- package/dist/server/src/camera/decoder/frame-scaler.d.ts +3 -1
- package/dist/server/src/camera/decoder/frame-scaler.js +36 -8
- package/dist/server/src/camera/decoder/frame-scaler.js.map +1 -1
- package/dist/server/src/camera/decoder/nvr-sink.d.ts +6 -0
- package/dist/server/src/camera/decoder/nvr-sink.js +1 -1
- package/dist/server/src/camera/decoder/nvr-sink.js.map +1 -1
- package/dist/server/src/camera/decoder/perf-tracker.d.ts +2 -0
- package/dist/server/src/camera/decoder/perf-tracker.js +4 -0
- package/dist/server/src/camera/decoder/perf-tracker.js.map +1 -1
- package/dist/server/src/camera/decoder/ptz/autotracker.d.ts +6 -1
- package/dist/server/src/camera/decoder/ptz/autotracker.js +107 -25
- package/dist/server/src/camera/decoder/ptz/autotracker.js.map +1 -1
- package/dist/server/src/camera/decoder/secondary-stage.d.ts +10 -8
- package/dist/server/src/camera/decoder/secondary-stage.js +145 -125
- package/dist/server/src/camera/decoder/secondary-stage.js.map +1 -1
- package/dist/server/src/camera/decoder/training-sink.d.ts +5 -2
- package/dist/server/src/camera/decoder/training-sink.js +30 -6
- package/dist/server/src/camera/decoder/training-sink.js.map +1 -1
- package/dist/server/src/camera/decoder/types.d.ts +6 -2
- package/dist/server/src/camera/decoder/types.js +4 -2
- package/dist/server/src/camera/decoder/types.js.map +1 -1
- package/dist/server/src/manager/coreManager.d.ts +2 -1
- package/dist/server/src/manager/coreManager.js +9 -2
- package/dist/server/src/manager/coreManager.js.map +1 -1
- package/dist/server/src/manager/trainingCandidateManager.d.ts +2 -1
- package/dist/server/src/manager/trainingCandidateManager.js +25 -3
- package/dist/server/src/manager/trainingCandidateManager.js.map +1 -1
- package/dist/server/src/manager/trainingSubmission.d.ts +5 -0
- package/dist/server/src/manager/trainingSubmission.js +73 -0
- package/dist/server/src/manager/trainingSubmission.js.map +1 -0
- package/dist/server/src/manager/types.d.ts +8 -2
- package/dist/server/src/manager/types.js.map +1 -1
- package/dist/server/src/plugins/runtime/node/proxy/coreManager.js +1 -1
- package/dist/server/src/plugins/runtime/node/proxy/coreManager.js.map +1 -1
- package/dist/server/src/plugins/runtime/python/proxy/camera_device.py +3 -0
- package/dist/server/src/plugins/runtime/python/proxy/core_manager.py +1 -1
- package/dist/server/src/plugins/runtime/python/proxy/sensor.py +2 -0
- package/dist/server/src/plugins/runtime/python/rpc/typings.py +1 -1
- package/dist/server/src/remote/api/routes/train.d.ts +44 -3
- package/dist/server/src/remote/api/routes/train.js +2 -2
- package/dist/server/src/remote/api/routes/train.js.map +1 -1
- package/dist/server/src/rpc/interfaces/core.d.ts +7 -3
- package/dist/server/src/rpc/interfaces/detection.d.ts +20 -3
- package/dist/server/src/rpc/server.d.ts +2 -0
- package/dist/server/src/rpc/server.js +8 -5
- package/dist/server/src/rpc/server.js.map +1 -1
- package/dist/server/src/sensors/registry.d.ts +3 -0
- package/dist/server/src/sensors/registry.js +44 -11
- package/dist/server/src/sensors/registry.js.map +1 -1
- package/dist/server/src/sensors/types.d.ts +1 -0
- package/dist/server/src/sensors/types.js +3 -0
- package/dist/server/src/sensors/types.js.map +1 -1
- package/dist/server/src/services/config/index.d.ts +1 -0
- package/dist/server/src/services/config/index.js +2 -0
- package/dist/server/src/services/config/index.js.map +1 -1
- package/dist/server/src/utils/image.d.ts +6 -0
- package/dist/server/src/utils/image.js +58 -22
- package/dist/server/src/utils/image.js.map +1 -1
- package/dist/server/src/workers/agent.js +2 -0
- package/dist/server/src/workers/agent.js.map +1 -1
- package/dist/server/src/workers/manager.d.ts +1 -0
- package/dist/server/src/workers/manager.js +22 -0
- package/dist/server/src/workers/manager.js.map +1 -1
- package/dist/server/src/workers/types.d.ts +5 -0
- package/dist/server/src/workers/types.js.map +1 -1
- package/npm-shrinkwrap.json +212 -171
- package/package.json +23 -23
- package/dist/interface/assets/404-C8EoOtBl.js +0 -1
- package/dist/interface/assets/About-Q7ZmOGgl.js +0 -1
- package/dist/interface/assets/Assistant-BQ6Ld-bt.css +0 -1
- package/dist/interface/assets/Assistant-DFLgklVe.js +0 -1
- package/dist/interface/assets/Automation-BSicfOGF.css +0 -1
- package/dist/interface/assets/Automation-D__qvx8c.js +0 -3
- package/dist/interface/assets/AutomationImport-CLQSdqg9.js +0 -2
- package/dist/interface/assets/AutomationStore-Dt6yTQDb.js +0 -2
- package/dist/interface/assets/AutomationStoreDetail-DqBrBhUI.js +0 -2
- package/dist/interface/assets/Automations-BH_7lYR7.js +0 -2
- package/dist/interface/assets/Camera-BW9ikKqh.css +0 -1
- package/dist/interface/assets/Camera-aquPHFwb.js +0 -2
- package/dist/interface/assets/CameraConsole-rhle_cfW.js +0 -7
- package/dist/interface/assets/Cameras-Bzy3P0xN.js +0 -651
- package/dist/interface/assets/Camview-Bri_T7Tq.css +0 -1
- package/dist/interface/assets/Camview-CjcQbtTl.js +0 -1
- package/dist/interface/assets/CertificateUpload-CWVu_52v.js +0 -1
- package/dist/interface/assets/Config-Dc1zKIPq.js +0 -2
- package/dist/interface/assets/ConfigActionAssistant-AfQfSqHZ.js +0 -1
- package/dist/interface/assets/ConfigActionCameraControl-BKQdHxqe.js +0 -1
- package/dist/interface/assets/ConfigActionDelay-B52HeJGb.js +0 -1
- package/dist/interface/assets/ConfigActionHttp-BP5gvpQc.js +0 -1
- package/dist/interface/assets/ConfigActionImageInput-DE2mSost.js +0 -1
- package/dist/interface/assets/ConfigActionMqtt-CYgnZjAE.js +0 -1
- package/dist/interface/assets/ConfigActionNotification-C3q53I4n.js +0 -1
- package/dist/interface/assets/ConfigActionNotificationControl-eDJ8r5ao.js +0 -1
- package/dist/interface/assets/ConfigActionOutput-DgYSYvy-.js +0 -1
- package/dist/interface/assets/ConfigActionPlugin-utolgAXk.js +0 -1
- package/dist/interface/assets/ConfigActionSensor-CmEKQPqs.js +0 -1
- package/dist/interface/assets/ConfigActionSnapshot-D7XucxVV.js +0 -1
- package/dist/interface/assets/ConfigActionVariable-C-Mjm3gr.js +0 -1
- package/dist/interface/assets/ConfigConditionIfElse-B24Rqb8y.js +0 -1
- package/dist/interface/assets/ConfigConditionSensorState-42-yFDmK.js +0 -1
- package/dist/interface/assets/ConfigConditionSwitch-DezH_nwm.js +0 -1
- package/dist/interface/assets/ConfigConditionTime-Cg2Lwznd.js +0 -1
- package/dist/interface/assets/ConfigSensorValueInput-YHBDCTZm.js +0 -1
- package/dist/interface/assets/ConfigTriggerDetection-DxEpodjG.js +0 -1
- package/dist/interface/assets/ConfigTriggerGeofence-Bye8syxc.js +0 -1
- package/dist/interface/assets/ConfigTriggerManual-s_lEDTV9.js +0 -1
- package/dist/interface/assets/ConfigTriggerMqtt-DqdZj7TU.js +0 -1
- package/dist/interface/assets/ConfigTriggerSchedule-Q559hn6g.js +0 -1
- package/dist/interface/assets/ConfigTriggerSensor-DIKkdbTF.js +0 -1
- package/dist/interface/assets/ConfigTriggerSystem-CwNZ4xEg.js +0 -1
- package/dist/interface/assets/ConfigTriggerWebhook-9ZC6X4mK.js +0 -1
- package/dist/interface/assets/Console-BqIDZ5vq.js +0 -1
- package/dist/interface/assets/CuiAssistantConversation-BmBhwrNh.css +0 -1
- package/dist/interface/assets/CuiAssistantConversation-CM7KdaX2.js +0 -5
- package/dist/interface/assets/CuiAutomationRunsDialog-CVjCLiVW.js +0 -1
- package/dist/interface/assets/CuiBottomSheet-CFohFiO2.js +0 -1
- package/dist/interface/assets/CuiBottomSheet-D75L0Zny.js +0 -1
- package/dist/interface/assets/CuiCameraPipCard-BQKk4fxY.css +0 -1
- package/dist/interface/assets/CuiCameraPipCard-eiJjYZ5W.js +0 -1
- package/dist/interface/assets/CuiCameraRecordings-DdEWkJrO.js +0 -1
- package/dist/interface/assets/CuiCameraShares-8mtgFsQ_.js +0 -1
- package/dist/interface/assets/CuiCameraTable-CmCT-XQF.js +0 -2
- package/dist/interface/assets/CuiCameraTable-DHrKoD9s.js +0 -1
- package/dist/interface/assets/CuiChartTable-v8sGY6PD.js +0 -1
- package/dist/interface/assets/CuiConsole-DYV-FUE0.js +0 -5
- package/dist/interface/assets/CuiDataTable-C0gsYYpg.js +0 -1
- package/dist/interface/assets/CuiLightControl-CFIwBj3C.js +0 -1
- package/dist/interface/assets/CuiList-9TVV8SB6.js +0 -1
- package/dist/interface/assets/CuiMarkdownContent-BYBQX_aF.js +0 -1
- package/dist/interface/assets/CuiMarkdownContent-DTAm-EDR.js +0 -1
- package/dist/interface/assets/CuiPluginCard-DEfqwUhQ.js +0 -2
- package/dist/interface/assets/CuiPluginCategoryChip-DhnIBJHa.js +0 -1
- package/dist/interface/assets/CuiPluginOAuthButton-DAuzNRAA.js +0 -2
- package/dist/interface/assets/CuiPluginTrustBadge-Bz710WwC.js +0 -1
- package/dist/interface/assets/CuiQRCode-B8-4GHSY.js +0 -1
- package/dist/interface/assets/CuiSchema-C_CHuKuf.js +0 -1
- package/dist/interface/assets/CuiTopNavbarItem-CNEnOPSh.js +0 -1
- package/dist/interface/assets/Faces-DRHMrrxh.js +0 -1
- package/dist/interface/assets/FirstSteps-Ci2Iqbe2.js +0 -1
- package/dist/interface/assets/Floorplan-Ci63Zd8W.css +0 -1
- package/dist/interface/assets/Floorplan-CqWIbDbh.js +0 -1
- package/dist/interface/assets/Instances-gzKFKB1l.js +0 -1
- package/dist/interface/assets/Logs-DL1yw_Pe.js +0 -6
- package/dist/interface/assets/Menu-C0GQ63aj.js +0 -1
- package/dist/interface/assets/Metrics-BYnnb7M0.js +0 -12
- package/dist/interface/assets/Metrics-DsHBab6t.css +0 -1
- package/dist/interface/assets/OAuthDeviceFlow-Zd6r9IHU.js +0 -1
- package/dist/interface/assets/Plugin-DJIrYUnZ.js +0 -1
- package/dist/interface/assets/Plugin-Qr_Q_Qfi.css +0 -1
- package/dist/interface/assets/PluginConsole-ag0jPZQ_.js +0 -7
- package/dist/interface/assets/PluginDetail-DmElwUuV.js +0 -2
- package/dist/interface/assets/PluginSchema-CxUujnVs.js +0 -1
- package/dist/interface/assets/PluginSearch-B-2zH2Xy.js +0 -1
- package/dist/interface/assets/PluginSearch-BqzngVRL.js +0 -2
- package/dist/interface/assets/PluginUpdateProgress-CFut0RAe.js +0 -1
- package/dist/interface/assets/Plugins-ZFcB_j6v.js +0 -1
- package/dist/interface/assets/RecentEventsFilter-CqeHhECT.js +0 -1
- package/dist/interface/assets/Recordings-BEKAn6QK.css +0 -1
- package/dist/interface/assets/Recordings-BJrtW9eG.js +0 -1
- package/dist/interface/assets/SensorEdit-Bi0gg-CL.js +0 -1
- package/dist/interface/assets/SensorHistory-q0UR3qMG.js +0 -1
- package/dist/interface/assets/Sensors-C_InhcHA.js +0 -2
- package/dist/interface/assets/Settings-Cv38rGWn.js +0 -1
- package/dist/interface/assets/Settings-D7495zbV.css +0 -1
- package/dist/interface/assets/SettingsAccount-B05739dn.js +0 -1
- package/dist/interface/assets/SettingsAccount-gm28wtbl.js +0 -1
- package/dist/interface/assets/SettingsAppearance-DdyYUgmV.js +0 -1
- package/dist/interface/assets/SettingsAppearance-DwUknDPV.js +0 -1
- package/dist/interface/assets/SettingsAssistant-ChHfkUKk.js +0 -1
- package/dist/interface/assets/SettingsBackup-DKwlPQhD.js +0 -1
- package/dist/interface/assets/SettingsList-D6hqnvUo.js +0 -1
- package/dist/interface/assets/SettingsMqtt-C01fgLY0.js +0 -1
- package/dist/interface/assets/SettingsNotifications-D47cIquQ.js +0 -1
- package/dist/interface/assets/SettingsPermissions-BeTCTrAf.js +0 -1
- package/dist/interface/assets/SettingsRecordings-mwL6Dalr.js +0 -1
- package/dist/interface/assets/SettingsRemote-CtP6Gz9C.css +0 -1
- package/dist/interface/assets/SettingsRemote-MhaShPIf.js +0 -2
- package/dist/interface/assets/SettingsSystem-BXnzXgqm.js +0 -2
- package/dist/interface/assets/SettingsUsers-D2mVlJin.js +0 -1
- package/dist/interface/assets/Terminal-C1UoXDRK.js +0 -4
- package/dist/interface/assets/Training-A5ynOv_l.js +0 -1
- package/dist/interface/assets/Training-C-ToeAl4.css +0 -1
- package/dist/interface/assets/Updates-kS_Tm8HD.js +0 -2
- package/dist/interface/assets/VariableInput-D9PfI8Ut.js +0 -1
- package/dist/interface/assets/VariableSuggestions-DArWzQuE.js +0 -1
- package/dist/interface/assets/VersionsHandler-BZVMpB2v.js +0 -7
- package/dist/interface/assets/VirtualSensorCreate-Cz-QFo4R.js +0 -1
- package/dist/interface/assets/Workers-2sc4VMi9.js +0 -2
- package/dist/interface/assets/Workers-DH59zE1C.css +0 -1
- package/dist/interface/assets/account-DwW7pBOb.js +0 -1
- package/dist/interface/assets/ace-DzzM-RlW.js +0 -1
- package/dist/interface/assets/ace.config-CCyX_Ohk.js +0 -1
- package/dist/interface/assets/alert-circle-BdUVAt1B.js +0 -1
- package/dist/interface/assets/alert-outline-IRxYbw0j.js +0 -1
- package/dist/interface/assets/api-CGfJbsTz.css +0 -2
- package/dist/interface/assets/api-CzwdnGAH.js +0 -1
- package/dist/interface/assets/api-DOpXVpef.js +0 -4
- package/dist/interface/assets/arrow-left-Bk-ZrOVr.js +0 -1
- package/dist/interface/assets/assistant-hGCAgv-f.js +0 -1
- package/dist/interface/assets/assistantModels-BsSgRsws.js +0 -1
- package/dist/interface/assets/auth-By-S-WEr.js +0 -1
- package/dist/interface/assets/automations-vwIwb2PQ.js +0 -1
- package/dist/interface/assets/back-filled-D-X19YMO.js +0 -1
- package/dist/interface/assets/bell-ring-DreEHgoT.js +0 -1
- package/dist/interface/assets/brain-DuDAg544.js +0 -1
- package/dist/interface/assets/cameraSources-BMhXvtFt.js +0 -1
- package/dist/interface/assets/cctv-DM-C_8_6.js +0 -1
- package/dist/interface/assets/check-circle-Bevuw8-0.js +0 -1
- package/dist/interface/assets/check-circle-outline-aMxkvksr.js +0 -1
- package/dist/interface/assets/chevron-down-CCFn9Z56.js +0 -1
- package/dist/interface/assets/chevron-up-CSImUM3_.js +0 -1
- package/dist/interface/assets/clock-outline-DH3WIEJt.js +0 -1
- package/dist/interface/assets/close-CMxyM4v9.js +0 -1
- package/dist/interface/assets/close-circle-CfgJCZ9A.js +0 -1
- package/dist/interface/assets/cloud-check-CbdFLIdR.js +0 -1
- package/dist/interface/assets/cloudHandoff-BnzjCpJ2.js +0 -1
- package/dist/interface/assets/config-BQxEwrK6.js +0 -1
- package/dist/interface/assets/content-copy-Bz49QPOI.js +0 -1
- package/dist/interface/assets/copy-DA6QQHRt.js +0 -1
- package/dist/interface/assets/cube-scan-IiH8zwm2.js +0 -1
- package/dist/interface/assets/database-refresh-outline-CIUDpcuq.js +0 -1
- package/dist/interface/assets/delete-Btu-UVx9.js +0 -1
- package/dist/interface/assets/dist-D_qWDAKp.js +0 -1
- package/dist/interface/assets/dots-vertical-D496SIss.js +0 -1
- package/dist/interface/assets/download-BSC7lwq_.js +0 -1
- package/dist/interface/assets/esm-Bn9gXwX4.js +0 -1
- package/dist/interface/assets/esm-BzM6y2-F.js +0 -1
- package/dist/interface/assets/esm-CP3JWrtj.js +0 -1
- package/dist/interface/assets/esm-CjAXkqCf.js +0 -1
- package/dist/interface/assets/esm-Cqxk-j1S.js +0 -1
- package/dist/interface/assets/esm-DFHd3JNU.js +0 -1
- package/dist/interface/assets/esm-DfMLJtug.js +0 -1
- package/dist/interface/assets/esm-DhDrpq7a.js +0 -1
- package/dist/interface/assets/esm-DvhM-SOd.js +0 -1
- package/dist/interface/assets/esm-G63bqygQ.js +0 -1
- package/dist/interface/assets/esm-Gn-Y59hU.js +0 -1
- package/dist/interface/assets/esm-KJSOz2vj.js +0 -1
- package/dist/interface/assets/esm-Ryfc94Tm.js +0 -1
- package/dist/interface/assets/esm-rSfI5Poy.js +0 -1
- package/dist/interface/assets/eventIcons-UQutPG3p.js +0 -1
- package/dist/interface/assets/eventLabels-BsPoPWS9.js +0 -1
- package/dist/interface/assets/eye-off-CSU0U8g7.js +0 -1
- package/dist/interface/assets/eye-off-outline-DCxLRGo_.js +0 -1
- package/dist/interface/assets/flowSchema-BPq6iHks.js +0 -1
- package/dist/interface/assets/help-circle-outline-Cr_yNhPi.js +0 -1
- package/dist/interface/assets/history-anuCbp1T.js +0 -1
- package/dist/interface/assets/home-N3bDR1vX.js +0 -1
- package/dist/interface/assets/information-outline-CMWIvLNB.js +0 -1
- package/dist/interface/assets/intercomService-CXcjcPa9.js +0 -1
- package/dist/interface/assets/lan-CYXjdk7L.js +0 -1
- package/dist/interface/assets/main-By4L33Im.js +0 -3
- package/dist/interface/assets/main-DVa5U7UB.css +0 -1
- package/dist/interface/assets/microphone-BB2pATI_.js +0 -1
- package/dist/interface/assets/minus-BCp3ZNKO.js +0 -1
- package/dist/interface/assets/mqtt-DE1KQ8Td.js +0 -1
- package/dist/interface/assets/native-CZJE8bTs.js +0 -1
- package/dist/interface/assets/native-DKZwialB.js +0 -1
- package/dist/interface/assets/nodeDefinitions-ByrqsENY.js +0 -1
- package/dist/interface/assets/notifications-BCyiD-TP.js +0 -1
- package/dist/interface/assets/pause-BQlxwAW2.js +0 -1
- package/dist/interface/assets/pencil-CDsNnEXi.js +0 -1
- package/dist/interface/assets/pencil-outline-CIQL5Kui.js +0 -1
- package/dist/interface/assets/plugin-DSEMkqaK.js +0 -1
- package/dist/interface/assets/plugins-BJPCV1YL.js +0 -1
- package/dist/interface/assets/plus-Bp4q9G7S.js +0 -1
- package/dist/interface/assets/plus-CySoovdr.js +0 -1
- package/dist/interface/assets/power-WmBLDR0-.js +0 -1
- package/dist/interface/assets/radar-CyYAmume.js +0 -1
- package/dist/interface/assets/refresh-CHTA3jVN.js +0 -1
- package/dist/interface/assets/restore-C8RNM5yX.js +0 -1
- package/dist/interface/assets/rooms-Dr4yiakO.js +0 -1
- package/dist/interface/assets/round-alt-arrow-left-bold-Gh5mi_yR.js +0 -1
- package/dist/interface/assets/search-BajCVmOI.js +0 -1
- package/dist/interface/assets/sensorIcons-DofElQ3w.js +0 -1
- package/dist/interface/assets/sensorSlots-D2KJGvPw.js +0 -1
- package/dist/interface/assets/sensors-3llrL7s3.js +0 -1
- package/dist/interface/assets/server-Dw5DD473.js +0 -1
- package/dist/interface/assets/settings-DnksaK7m.js +0 -1
- package/dist/interface/assets/source-branch-CzqIPffP.js +0 -1
- package/dist/interface/assets/theme-C85LJhOY.js +0 -1
- package/dist/interface/assets/trash-2-DJeEhHf4.js +0 -1
- package/dist/interface/assets/trash-can-outline-DrT6iw7I.js +0 -1
- package/dist/interface/assets/trash-fill-Bb_-UicM.js +0 -1
- package/dist/interface/assets/trash2-Dsl8gfxq.js +0 -1
- package/dist/interface/assets/types-CPhy0Ovw.js +0 -1
- package/dist/interface/assets/types-DYKmSGl4.js +0 -1
- package/dist/interface/assets/types-i1kTodPP.js +0 -1
- package/dist/interface/assets/undo-DoqJW-k7.js +0 -1
- package/dist/interface/assets/ungrouped-BlheTJCh.css +0 -1
- package/dist/interface/assets/ungrouped-C2CWO39a.js +0 -1
- package/dist/interface/assets/updates-C2LhMkNR.js +0 -1
- package/dist/interface/assets/upload-C3w1XH-o.js +0 -1
- package/dist/interface/assets/upload-DtIcwiNC.js +0 -1
- package/dist/interface/assets/useAppVersion-DkazK9Vu.js +0 -1
- package/dist/interface/assets/useAssistantActions-BZP6NL18.js +0 -1
- package/dist/interface/assets/useBackupRestore-DMQW_CVC.js +0 -1
- package/dist/interface/assets/useCameraOptions-DnI0xLrX.js +0 -1
- package/dist/interface/assets/useKeyboardInset-Cr7SxKGN.js +0 -1
- package/dist/interface/assets/useLogsSocket-C3Y8S0Ar.js +0 -1
- package/dist/interface/assets/useNavLayout-C9pcDuVP.js +0 -1
- package/dist/interface/assets/usePermissions-CCTxwXF0.js +0 -1
- package/dist/interface/assets/usePluginUpdates-DBhLWAua.js +0 -1
- package/dist/interface/assets/usePushRegistration-CPRVdLAx.js +0 -2
- package/dist/interface/assets/useServerRestart-bScBLJ9r.js +0 -1
- package/dist/interface/assets/useStreamStatus-Bfh-WmLH.js +0 -1
- package/dist/interface/assets/useTabSwipe-C_QOrvSW.js +0 -1
- package/dist/interface/assets/useUpdateChannel-g0h_4c55.js +0 -1
- package/dist/interface/assets/useUpdatesSocket-CxrLRETs.js +0 -1
- package/dist/interface/assets/useUserOptions-DN0t3gBr.js +0 -1
- package/dist/interface/assets/variable-ywTlRfo5.js +0 -1
- package/dist/interface/assets/vendor-ace-CvEoip98.js +0 -1085
- package/dist/interface/assets/vendor-cameraui-B28aGJJD.js +0 -2326
- package/dist/interface/assets/vendor-capacitor-Bs_WzL0Q.js +0 -2
- package/dist/interface/assets/vendor-chart-DBK083Hu.js +0 -3
- package/dist/interface/assets/vendor-core-DIa0tPNH.js +0 -1
- package/dist/interface/assets/vendor-dnd-DGQLvX6Y.js +0 -2
- package/dist/interface/assets/vendor-draggabilly-D8CK6M-y.js +0 -1
- package/dist/interface/assets/vendor-gFkr2qsZ.js +0 -23
- package/dist/interface/assets/vendor-leaflet-DkAk6mAj.js +0 -1
- package/dist/interface/assets/vendor-markdown-qHIinIUE.js +0 -14
- package/dist/interface/assets/vendor-primevue-CZKUAkMA.js +0 -3942
- package/dist/interface/assets/vendor-vueflow-bSwRZ9X8.js +0 -26
- package/dist/interface/assets/web-BDNQnMmA.js +0 -1
- package/dist/interface/assets/web-B_9Qyt8E.js +0 -1
- package/dist/interface/assets/web-BhJykCtq.js +0 -1
- package/dist/interface/assets/web-BjKL51lK-wWFeZlLg.js +0 -1
- package/dist/interface/assets/web-C7nJwIOa.js +0 -1
- package/dist/interface/assets/web-CGJsJQDb.js +0 -1
- package/dist/interface/assets/web-CJwASxrl.js +0 -1
- package/dist/interface/assets/web-CLe0L31Y.js +0 -1
- package/dist/interface/assets/web-DEv1hAn1.js +0 -1
- package/dist/interface/assets/web-DaeQvsXT.js +0 -1
- package/dist/interface/assets/web-H3-wNunW.js +0 -1
- package/dist/interface/assets/web-LCdyqJq1.js +0 -1
- package/dist/interface/assets/web-XZWYTK65.js +0 -1
- package/dist/interface/assets/web-rU5hlxxW.js +0 -1
- package/dist/interface/assets/webhook-CWKf2Qxu.js +0 -1
- package/dist/interface/assets/workbox-window.prod.es5-BEYAF-e-.js +0 -1
- package/dist/interface/assets/zoom-in-CHkXAWHy.js +0 -1
- package/dist/interface/ha/404-tl2VQ3qy.js +0 -60
- package/dist/interface/ha/About-Cn7KOblU.js +0 -55
- package/dist/interface/ha/Assistant-DG2GGda0.js +0 -9361
- package/dist/interface/ha/Automation-D0_WpXx4.js +0 -2025
- package/dist/interface/ha/AutomationImport-DdC3dEaC.js +0 -206
- package/dist/interface/ha/AutomationStore-BrLn4oBx.js +0 -336
- package/dist/interface/ha/AutomationStoreDetail-DoppNsNc.js +0 -122
- package/dist/interface/ha/Automations-BaUJ9pVq.js +0 -424
- package/dist/interface/ha/Camera-Cj5ImvZG.js +0 -657
- package/dist/interface/ha/CameraConsole-7MhlS2VK.js +0 -52
- package/dist/interface/ha/Cameras-vHYz8uSO.js +0 -1969
- package/dist/interface/ha/Camview-BEglAx26.js +0 -1331
- package/dist/interface/ha/Config-CHiK--zP.js +0 -356
- package/dist/interface/ha/ConfigActionAssistant-DynduZYV.js +0 -182
- package/dist/interface/ha/ConfigActionCameraControl-BEYePssz.js +0 -152
- package/dist/interface/ha/ConfigActionHttp-h0vRWqZ5.js +0 -134
- package/dist/interface/ha/ConfigActionImageInput-B9GMZYAR.js +0 -171
- package/dist/interface/ha/ConfigActionMqtt-BEQpHBgf.js +0 -81
- package/dist/interface/ha/ConfigActionNotification-BYsz8_aS.js +0 -199
- package/dist/interface/ha/ConfigActionNotificationControl-BxmIWVE8.js +0 -111
- package/dist/interface/ha/ConfigActionOutput-DTOQSa1S.js +0 -98
- package/dist/interface/ha/ConfigActionPlugin-NOsUs3QI.js +0 -172
- package/dist/interface/ha/ConfigActionSensor-YWnsH_LV.js +0 -139
- package/dist/interface/ha/ConfigActionSnapshot-DHJnTvin.js +0 -48
- package/dist/interface/ha/ConfigActionVariable-C7UFnvW0.js +0 -88
- package/dist/interface/ha/ConfigConditionIfElse-CAHbuhH3.js +0 -124
- package/dist/interface/ha/ConfigConditionSensorState-CE6okUeb.js +0 -192
- package/dist/interface/ha/ConfigConditionSwitch-D5FULaTy.js +0 -128
- package/dist/interface/ha/ConfigSensorValueInput-mo6Gs_aZ.js +0 -170
- package/dist/interface/ha/ConfigTriggerDetection-Bt-OhHtM.js +0 -241
- package/dist/interface/ha/ConfigTriggerGeofence-Cw3jV5qD.js +0 -4888
- package/dist/interface/ha/ConfigTriggerMqtt-BXeV82UG.js +0 -134
- package/dist/interface/ha/ConfigTriggerSensor-Baqq--nJ.js +0 -73
- package/dist/interface/ha/ConfigTriggerSystem-braUVGzW.js +0 -192
- package/dist/interface/ha/ConfigTriggerWebhook-Dm45r-1C.js +0 -94
- package/dist/interface/ha/Console-q3TCsxYo.js +0 -348
- package/dist/interface/ha/CuiAutomationRunsDialog-DO6h5Tc4.js +0 -130
- package/dist/interface/ha/CuiBottomSheet-B7ldz0xi.js +0 -270
- package/dist/interface/ha/CuiCameraRecordings-Dq1Vh3qA.js +0 -551
- package/dist/interface/ha/CuiCameraShares-DBqcpevG.js +0 -121
- package/dist/interface/ha/CuiCameraTable-kL8rK-Uv.js +0 -169
- package/dist/interface/ha/CuiChartTable-BrFyiSt_.js +0 -6801
- package/dist/interface/ha/CuiConsole-DpeXZmJd.js +0 -244
- package/dist/interface/ha/CuiDataTable-BtqzIz0o.js +0 -8732
- package/dist/interface/ha/CuiList-CU2NJ1K6.js +0 -57
- package/dist/interface/ha/CuiPluginCard-lBLypaN4.js +0 -769
- package/dist/interface/ha/CuiPluginOAuthButton-CuGauZJA.js +0 -79
- package/dist/interface/ha/CuiPluginTrustBadge-BofBmRYc.js +0 -123
- package/dist/interface/ha/CuiQRCode-CdK9bwKb.js +0 -86
- package/dist/interface/ha/CuiSchema-DqkCLv9Y.js +0 -963
- package/dist/interface/ha/CuiTopNavbarItem-C2VZB7WV.js +0 -140
- package/dist/interface/ha/Faces-Crfi-75Z.js +0 -1441
- package/dist/interface/ha/FirstSteps-CKVG86pf.js +0 -251
- package/dist/interface/ha/Floorplan-CH9_-6hk.js +0 -3657
- package/dist/interface/ha/Instances-5gZdPPDA.js +0 -680
- package/dist/interface/ha/Logs-BkzEM70F.js +0 -418
- package/dist/interface/ha/Menu-BuT3_Ggx.js +0 -156
- package/dist/interface/ha/Metrics-BGrzu0bu.js +0 -1447
- package/dist/interface/ha/OAuthDeviceFlow-BEJtegqy.js +0 -112
- package/dist/interface/ha/Plugin-Bnp2jiC2.js +0 -1544
- package/dist/interface/ha/PluginConsole-CmsuPVMz.js +0 -56
- package/dist/interface/ha/PluginDetail-BCNx7vHr.js +0 -805
- package/dist/interface/ha/PluginSearch-DOdhuxgM.js +0 -462
- package/dist/interface/ha/PluginUpdateProgress-CwkKc8Tr.js +0 -34
- package/dist/interface/ha/Plugins-BrFowCdC.js +0 -692
- package/dist/interface/ha/RecentEventsFilter-9ZkDHD1g.js +0 -79
- package/dist/interface/ha/Recordings-BZhf39pJ.js +0 -1539
- package/dist/interface/ha/SensorEdit-Ds6WbN4A.js +0 -1462
- package/dist/interface/ha/SensorHistory-CoTIYTJx.js +0 -54
- package/dist/interface/ha/Sensors-DZ2MKdlh.js +0 -1400
- package/dist/interface/ha/Settings-D3JKr430.js +0 -218
- package/dist/interface/ha/SettingsAccount-cvtlSKZw.js +0 -971
- package/dist/interface/ha/SettingsAppearance-CaKuOHRu.js +0 -220
- package/dist/interface/ha/SettingsAssistant-vWVjAUqQ.js +0 -2025
- package/dist/interface/ha/SettingsBackup-CvzL_bVf.js +0 -556
- package/dist/interface/ha/SettingsList-C0Ec8x-H.js +0 -40
- package/dist/interface/ha/SettingsMqtt-COnq-QM5.js +0 -526
- package/dist/interface/ha/SettingsNotifications-BZ68bQzO.js +0 -529
- package/dist/interface/ha/SettingsPermissions-Jh0FuIF7.js +0 -84
- package/dist/interface/ha/SettingsRecordings-BPtNNpDa.js +0 -152
- package/dist/interface/ha/SettingsRemote-BXG8IYjf.js +0 -1810
- package/dist/interface/ha/SettingsSystem-_jHBUhws.js +0 -376
- package/dist/interface/ha/SettingsUsers-CzGj_RJN.js +0 -379
- package/dist/interface/ha/Terminal-BP3b8IBP.js +0 -612
- package/dist/interface/ha/Training-C2-6DgY0.js +0 -1699
- package/dist/interface/ha/Updates-BMZsEhmy.js +0 -343
- package/dist/interface/ha/VariableInput-DmI7skCD.js +0 -52
- package/dist/interface/ha/VersionsHandler-DJd4NqtD.js +0 -216
- package/dist/interface/ha/VirtualSensorCreate-DmtGYvAn.js +0 -101
- package/dist/interface/ha/Workers-2HTPHgKV.js +0 -765
- package/dist/interface/ha/ace-B3bPzJu9.js +0 -13236
- package/dist/interface/ha/ace.config-Dt55Nqby.js +0 -1429
- package/dist/interface/ha/api-BelbnLQO.js +0 -62346
- package/dist/interface/ha/api-sy4rqV2N.js +0 -29
- package/dist/interface/ha/assistant-C6KYXJfi.js +0 -349
- package/dist/interface/ha/auth-Da66mVEd.js +0 -271
- package/dist/interface/ha/automationBlueprint-hlqqM17r.js +0 -250
- package/dist/interface/ha/cards-BFRRfuM7.js +0 -13436
- package/dist/interface/ha/config-Cd7JNMpD.js +0 -116
- package/dist/interface/ha/dist-BIngHzHx.js +0 -287
- package/dist/interface/ha/dist-BybVYMVs.js +0 -3248
- package/dist/interface/ha/eventIcons-BFNUgeGr.js +0 -676
- package/dist/interface/ha/eventLabels-B4C1_4vT.js +0 -42
- package/dist/interface/ha/eye-off-outline-ACbzsGuK.js +0 -19
- package/dist/interface/ha/intercomService-B7HkLs6z.js +0 -1414
- package/dist/interface/ha/mqtt-UZfptWJl.js +0 -56
- package/dist/interface/ha/notifications-DTHM8fS-.js +0 -159
- package/dist/interface/ha/pinia-BokSpDzj.js +0 -7656
- package/dist/interface/ha/plugins-Bwp_GfaX.js +0 -592
- package/dist/interface/ha/protocol-BB4jdtUC-DW3jl2tV.js +0 -708
- package/dist/interface/ha/rooms-BvaD0r0q.js +0 -45
- package/dist/interface/ha/server-OWdtITVa.js +0 -239
- package/dist/interface/ha/types-BFJjyMZe.js +0 -1073
- package/dist/interface/ha/ungrouped-x00DHNHO.js +0 -1311
- package/dist/interface/ha/updates-C03Qf3Il.js +0 -341
- package/dist/interface/ha/useAppVersion-CrMd9CC9.js +0 -22
- package/dist/interface/ha/useAssistantActions-S1FrNe9b.js +0 -29
- package/dist/interface/ha/useKeyboardInset-DwUQCWHC.js +0 -27
- package/dist/interface/ha/useLogsSocket-C6k217mW.js +0 -59
- package/dist/interface/ha/useNavLayout-DhuQE024.js +0 -125
- package/dist/interface/ha/usePermissions-DaE_wFch.js +0 -72
- package/dist/interface/ha/useServerRestart-CYaen2r6.js +0 -23
- package/dist/interface/ha/useTabSwipe-DAmCFlgg.js +0 -45
- package/dist/interface/ha/useUpdateChannel-Dr1EoU2X.js +0 -22
- package/dist/interface/ha/useUpdatesSocket-C8Gmhemh.js +0 -34
- package/dist/interface/ha/useUserOptions-BB5wk3Bq.js +0 -15
- package/dist/interface/workbox-778a14ff.js +0 -1
|
@@ -1,1429 +0,0 @@
|
|
|
1
|
-
import { o as e, t } from "./rolldown-runtime-CEFd7nDs.js";
|
|
2
|
-
import { t as n } from "./ace-B3bPzJu9.js";
|
|
3
|
-
//#region node_modules/ace-builds/src-noconflict/mode-yaml.js?url
|
|
4
|
-
var r = /* @__PURE__ */ e(n(), 1);
|
|
5
|
-
(/* @__PURE__ */ t(((e, t) => {
|
|
6
|
-
ace.define("ace/snippets", [
|
|
7
|
-
"require",
|
|
8
|
-
"exports",
|
|
9
|
-
"module",
|
|
10
|
-
"ace/lib/dom",
|
|
11
|
-
"ace/lib/oop",
|
|
12
|
-
"ace/lib/event_emitter",
|
|
13
|
-
"ace/lib/lang",
|
|
14
|
-
"ace/range",
|
|
15
|
-
"ace/range_list",
|
|
16
|
-
"ace/keyboard/hash_handler",
|
|
17
|
-
"ace/tokenizer",
|
|
18
|
-
"ace/clipboard",
|
|
19
|
-
"ace/editor"
|
|
20
|
-
], function(e, t, n) {
|
|
21
|
-
var r = e("./lib/dom"), i = e("./lib/oop"), a = e("./lib/event_emitter").EventEmitter, o = e("./lib/lang"), s = e("./range").Range, c = e("./range_list").RangeList, l = e("./keyboard/hash_handler").HashHandler, u = e("./tokenizer").Tokenizer, d = e("./clipboard"), f = {
|
|
22
|
-
CURRENT_WORD: function(e) {
|
|
23
|
-
return e.session.getTextRange(e.session.getWordRange());
|
|
24
|
-
},
|
|
25
|
-
SELECTION: function(e, t, n) {
|
|
26
|
-
var r = e.session.getTextRange();
|
|
27
|
-
return n ? r.replace(/\n\r?([ \t]*\S)/g, "\n" + n + "$1") : r;
|
|
28
|
-
},
|
|
29
|
-
CURRENT_LINE: function(e) {
|
|
30
|
-
return e.session.getLine(e.getCursorPosition().row);
|
|
31
|
-
},
|
|
32
|
-
PREV_LINE: function(e) {
|
|
33
|
-
return e.session.getLine(e.getCursorPosition().row - 1);
|
|
34
|
-
},
|
|
35
|
-
LINE_INDEX: function(e) {
|
|
36
|
-
return e.getCursorPosition().row;
|
|
37
|
-
},
|
|
38
|
-
LINE_NUMBER: function(e) {
|
|
39
|
-
return e.getCursorPosition().row + 1;
|
|
40
|
-
},
|
|
41
|
-
SOFT_TABS: function(e) {
|
|
42
|
-
return e.session.getUseSoftTabs() ? "YES" : "NO";
|
|
43
|
-
},
|
|
44
|
-
TAB_SIZE: function(e) {
|
|
45
|
-
return e.session.getTabSize();
|
|
46
|
-
},
|
|
47
|
-
CLIPBOARD: function(e) {
|
|
48
|
-
return d.getText && d.getText();
|
|
49
|
-
},
|
|
50
|
-
FILENAME: function(e) {
|
|
51
|
-
return /[^/\\]*$/.exec(this.FILEPATH(e))[0];
|
|
52
|
-
},
|
|
53
|
-
FILENAME_BASE: function(e) {
|
|
54
|
-
return /[^/\\]*$/.exec(this.FILEPATH(e))[0].replace(/\.[^.]*$/, "");
|
|
55
|
-
},
|
|
56
|
-
DIRECTORY: function(e) {
|
|
57
|
-
return this.FILEPATH(e).replace(/[^/\\]*$/, "");
|
|
58
|
-
},
|
|
59
|
-
FILEPATH: function(e) {
|
|
60
|
-
return "/not implemented.txt";
|
|
61
|
-
},
|
|
62
|
-
WORKSPACE_NAME: function() {
|
|
63
|
-
return "Unknown";
|
|
64
|
-
},
|
|
65
|
-
FULLNAME: function() {
|
|
66
|
-
return "Unknown";
|
|
67
|
-
},
|
|
68
|
-
BLOCK_COMMENT_START: function(e) {
|
|
69
|
-
var t = e.session.$mode || {};
|
|
70
|
-
return t.blockComment && t.blockComment.start || "";
|
|
71
|
-
},
|
|
72
|
-
BLOCK_COMMENT_END: function(e) {
|
|
73
|
-
var t = e.session.$mode || {};
|
|
74
|
-
return t.blockComment && t.blockComment.end || "";
|
|
75
|
-
},
|
|
76
|
-
LINE_COMMENT: function(e) {
|
|
77
|
-
return (e.session.$mode || {}).lineCommentStart || "";
|
|
78
|
-
},
|
|
79
|
-
CURRENT_YEAR: p.bind(null, { year: "numeric" }),
|
|
80
|
-
CURRENT_YEAR_SHORT: p.bind(null, { year: "2-digit" }),
|
|
81
|
-
CURRENT_MONTH: p.bind(null, { month: "numeric" }),
|
|
82
|
-
CURRENT_MONTH_NAME: p.bind(null, { month: "long" }),
|
|
83
|
-
CURRENT_MONTH_NAME_SHORT: p.bind(null, { month: "short" }),
|
|
84
|
-
CURRENT_DATE: p.bind(null, { day: "2-digit" }),
|
|
85
|
-
CURRENT_DAY_NAME: p.bind(null, { weekday: "long" }),
|
|
86
|
-
CURRENT_DAY_NAME_SHORT: p.bind(null, { weekday: "short" }),
|
|
87
|
-
CURRENT_HOUR: p.bind(null, {
|
|
88
|
-
hour: "2-digit",
|
|
89
|
-
hour12: !1
|
|
90
|
-
}),
|
|
91
|
-
CURRENT_MINUTE: p.bind(null, { minute: "2-digit" }),
|
|
92
|
-
CURRENT_SECOND: p.bind(null, { second: "2-digit" })
|
|
93
|
-
};
|
|
94
|
-
f.SELECTED_TEXT = f.SELECTION;
|
|
95
|
-
function p(e) {
|
|
96
|
-
var t = (/* @__PURE__ */ new Date()).toLocaleString("en-us", e);
|
|
97
|
-
return t.length == 1 ? "0" + t : t;
|
|
98
|
-
}
|
|
99
|
-
var m = function() {
|
|
100
|
-
function e() {
|
|
101
|
-
this.snippetMap = {}, this.snippetNameMap = {}, this.variables = f;
|
|
102
|
-
}
|
|
103
|
-
return e.prototype.getTokenizer = function() {
|
|
104
|
-
return e.$tokenizer || this.createTokenizer();
|
|
105
|
-
}, e.prototype.createTokenizer = function() {
|
|
106
|
-
function t(e) {
|
|
107
|
-
return e = e.substr(1), /^\d+$/.test(e) ? [{ tabstopId: parseInt(e, 10) }] : [{ text: e }];
|
|
108
|
-
}
|
|
109
|
-
function n(e) {
|
|
110
|
-
return "(?:[^\\\\" + e + "]|\\\\.)";
|
|
111
|
-
}
|
|
112
|
-
var r = {
|
|
113
|
-
regex: "/(" + n("/") + "+)/",
|
|
114
|
-
onMatch: function(e, t, n) {
|
|
115
|
-
var r = n[0];
|
|
116
|
-
return r.fmtString = !0, r.guard = e.slice(1, -1), r.flag = "", "";
|
|
117
|
-
},
|
|
118
|
-
next: "formatString"
|
|
119
|
-
};
|
|
120
|
-
return e.$tokenizer = new u({
|
|
121
|
-
start: [
|
|
122
|
-
{
|
|
123
|
-
regex: /\\./,
|
|
124
|
-
onMatch: function(e, t, n) {
|
|
125
|
-
var r = e[1];
|
|
126
|
-
return (r == "}" && n.length || "`$\\".indexOf(r) != -1) && (e = r), [e];
|
|
127
|
-
}
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
regex: /}/,
|
|
131
|
-
onMatch: function(e, t, n) {
|
|
132
|
-
return [n.length ? n.shift() : e];
|
|
133
|
-
}
|
|
134
|
-
},
|
|
135
|
-
{
|
|
136
|
-
regex: /\$(?:\d+|\w+)/,
|
|
137
|
-
onMatch: t
|
|
138
|
-
},
|
|
139
|
-
{
|
|
140
|
-
regex: /\$\{[\dA-Z_a-z]+/,
|
|
141
|
-
onMatch: function(e, n, r) {
|
|
142
|
-
var i = t(e.substr(1));
|
|
143
|
-
return r.unshift(i[0]), i;
|
|
144
|
-
},
|
|
145
|
-
next: "snippetVar"
|
|
146
|
-
},
|
|
147
|
-
{
|
|
148
|
-
regex: /\n/,
|
|
149
|
-
token: "newline",
|
|
150
|
-
merge: !1
|
|
151
|
-
}
|
|
152
|
-
],
|
|
153
|
-
snippetVar: [
|
|
154
|
-
{
|
|
155
|
-
regex: "\\|" + n("\\|") + "*\\|",
|
|
156
|
-
onMatch: function(e, t, n) {
|
|
157
|
-
var r = e.slice(1, -1).replace(/\\[,|\\]|,/g, function(e) {
|
|
158
|
-
return e.length == 2 ? e[1] : "\0";
|
|
159
|
-
}).split("\0").map(function(e) {
|
|
160
|
-
return { value: e };
|
|
161
|
-
});
|
|
162
|
-
return n[0].choices = r, [r[0]];
|
|
163
|
-
},
|
|
164
|
-
next: "start"
|
|
165
|
-
},
|
|
166
|
-
r,
|
|
167
|
-
{
|
|
168
|
-
regex: "([^:}\\\\]|\\\\.)*:?",
|
|
169
|
-
token: "",
|
|
170
|
-
next: "start"
|
|
171
|
-
}
|
|
172
|
-
],
|
|
173
|
-
formatString: [
|
|
174
|
-
{
|
|
175
|
-
regex: /:/,
|
|
176
|
-
onMatch: function(e, t, n) {
|
|
177
|
-
return n.length && n[0].expectElse ? (n[0].expectElse = !1, n[0].ifEnd = { elseEnd: n[0] }, [n[0].ifEnd]) : ":";
|
|
178
|
-
}
|
|
179
|
-
},
|
|
180
|
-
{
|
|
181
|
-
regex: /\\./,
|
|
182
|
-
onMatch: function(e, t, n) {
|
|
183
|
-
var r = e[1];
|
|
184
|
-
return r == "}" && n.length ? e = r : "`$\\".indexOf(r) == -1 ? r == "n" ? e = "\n" : r == "t" ? e = " " : "ulULE".indexOf(r) != -1 && (e = {
|
|
185
|
-
changeCase: r,
|
|
186
|
-
local: r > "a"
|
|
187
|
-
}) : e = r, [e];
|
|
188
|
-
}
|
|
189
|
-
},
|
|
190
|
-
{
|
|
191
|
-
regex: "/\\w*}",
|
|
192
|
-
onMatch: function(e, t, n) {
|
|
193
|
-
var r = n.shift();
|
|
194
|
-
return r && (r.flag = e.slice(1, -1)), this.next = r && r.tabstopId ? "start" : "", [r || e];
|
|
195
|
-
},
|
|
196
|
-
next: "start"
|
|
197
|
-
},
|
|
198
|
-
{
|
|
199
|
-
regex: /\$(?:\d+|\w+)/,
|
|
200
|
-
onMatch: function(e, t, n) {
|
|
201
|
-
return [{ text: e.slice(1) }];
|
|
202
|
-
}
|
|
203
|
-
},
|
|
204
|
-
{
|
|
205
|
-
regex: /\${\w+/,
|
|
206
|
-
onMatch: function(e, t, n) {
|
|
207
|
-
var r = { text: e.slice(2) };
|
|
208
|
-
return n.unshift(r), [r];
|
|
209
|
-
},
|
|
210
|
-
next: "formatStringVar"
|
|
211
|
-
},
|
|
212
|
-
{
|
|
213
|
-
regex: /\n/,
|
|
214
|
-
token: "newline",
|
|
215
|
-
merge: !1
|
|
216
|
-
},
|
|
217
|
-
{
|
|
218
|
-
regex: /}/,
|
|
219
|
-
onMatch: function(e, t, n) {
|
|
220
|
-
var r = n.shift();
|
|
221
|
-
return this.next = r && r.tabstopId ? "start" : "", [r || e];
|
|
222
|
-
},
|
|
223
|
-
next: "start"
|
|
224
|
-
}
|
|
225
|
-
],
|
|
226
|
-
formatStringVar: [
|
|
227
|
-
{
|
|
228
|
-
regex: /:\/\w+}/,
|
|
229
|
-
onMatch: function(e, t, n) {
|
|
230
|
-
var r = n[0];
|
|
231
|
-
return r.formatFunction = e.slice(2, -1), [n.shift()];
|
|
232
|
-
},
|
|
233
|
-
next: "formatString"
|
|
234
|
-
},
|
|
235
|
-
r,
|
|
236
|
-
{
|
|
237
|
-
regex: /:[\?\-+]?/,
|
|
238
|
-
onMatch: function(e, t, n) {
|
|
239
|
-
e[1] == "+" && (n[0].ifEnd = n[0]), e[1] == "?" && (n[0].expectElse = !0);
|
|
240
|
-
},
|
|
241
|
-
next: "formatString"
|
|
242
|
-
},
|
|
243
|
-
{
|
|
244
|
-
regex: "([^:}\\\\]|\\\\.)*:?",
|
|
245
|
-
token: "",
|
|
246
|
-
next: "formatString"
|
|
247
|
-
}
|
|
248
|
-
]
|
|
249
|
-
}), e.$tokenizer;
|
|
250
|
-
}, e.prototype.tokenizeTmSnippet = function(e, t) {
|
|
251
|
-
return this.getTokenizer().getLineTokens(e, t).tokens.map(function(e) {
|
|
252
|
-
return e.value || e;
|
|
253
|
-
});
|
|
254
|
-
}, e.prototype.getVariableValue = function(e, t, n) {
|
|
255
|
-
if (/^\d+$/.test(t)) return (this.variables.__ || {})[t] || "";
|
|
256
|
-
if (/^[A-Z]\d+$/.test(t)) return (this.variables[t[0] + "__"] || {})[t.substr(1)] || "";
|
|
257
|
-
if (t = t.replace(/^TM_/, ""), !this.variables.hasOwnProperty(t)) return "";
|
|
258
|
-
var r = this.variables[t];
|
|
259
|
-
return typeof r == "function" && (r = this.variables[t](e, t, n)), r ?? "";
|
|
260
|
-
}, e.prototype.tmStrFormat = function(e, t, n) {
|
|
261
|
-
if (!t.fmt) return e;
|
|
262
|
-
var r = t.flag || "", i = t.guard;
|
|
263
|
-
i = new RegExp(i, r.replace(/[^gim]/g, ""));
|
|
264
|
-
var a = typeof t.fmt == "string" ? this.tokenizeTmSnippet(t.fmt, "formatString") : t.fmt, o = this;
|
|
265
|
-
return e.replace(i, function() {
|
|
266
|
-
var e = o.variables.__;
|
|
267
|
-
o.variables.__ = [].slice.call(arguments);
|
|
268
|
-
for (var t = o.resolveVariables(a, n), r = "E", i = 0; i < t.length; i++) {
|
|
269
|
-
var s = t[i];
|
|
270
|
-
if (typeof s == "object") {
|
|
271
|
-
if (t[i] = "", s.changeCase && s.local) {
|
|
272
|
-
var c = t[i + 1];
|
|
273
|
-
c && typeof c == "string" && (s.changeCase == "u" ? t[i] = c[0].toUpperCase() : t[i] = c[0].toLowerCase(), t[i + 1] = c.substr(1));
|
|
274
|
-
} else s.changeCase && (r = s.changeCase);
|
|
275
|
-
} else r == "U" ? t[i] = s.toUpperCase() : r == "L" && (t[i] = s.toLowerCase());
|
|
276
|
-
}
|
|
277
|
-
return o.variables.__ = e, t.join("");
|
|
278
|
-
});
|
|
279
|
-
}, e.prototype.tmFormatFunction = function(e, t, n) {
|
|
280
|
-
return t.formatFunction == "upcase" ? e.toUpperCase() : t.formatFunction == "downcase" ? e.toLowerCase() : e;
|
|
281
|
-
}, e.prototype.resolveVariables = function(e, t) {
|
|
282
|
-
for (var n = [], r = "", i = !0, a = 0; a < e.length; a++) {
|
|
283
|
-
var o = e[a];
|
|
284
|
-
if (typeof o == "string") {
|
|
285
|
-
n.push(o), o == "\n" ? (i = !0, r = "") : i &&= (r = /^\t*/.exec(o)[0], /\S/.test(o));
|
|
286
|
-
continue;
|
|
287
|
-
}
|
|
288
|
-
if (o) {
|
|
289
|
-
if (i = !1, o.fmtString) {
|
|
290
|
-
var s = e.indexOf(o, a + 1);
|
|
291
|
-
s == -1 && (s = e.length), o.fmt = e.slice(a + 1, s), a = s;
|
|
292
|
-
}
|
|
293
|
-
if (o.text) {
|
|
294
|
-
var c = this.getVariableValue(t, o.text, r) + "";
|
|
295
|
-
o.fmtString && (c = this.tmStrFormat(c, o, t)), o.formatFunction && (c = this.tmFormatFunction(c, o, t)), c && !o.ifEnd ? (n.push(c), l(o)) : !c && o.ifEnd && l(o.ifEnd);
|
|
296
|
-
} else o.elseEnd ? l(o.elseEnd) : o.tabstopId == null ? o.changeCase != null && n.push(o) : n.push(o);
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
function l(t) {
|
|
300
|
-
var n = e.indexOf(t, a + 1);
|
|
301
|
-
n != -1 && (a = n);
|
|
302
|
-
}
|
|
303
|
-
return n;
|
|
304
|
-
}, e.prototype.getDisplayTextForSnippet = function(e, t) {
|
|
305
|
-
return h.call(this, e, t).text;
|
|
306
|
-
}, e.prototype.insertSnippetForSelection = function(e, t, n) {
|
|
307
|
-
n === void 0 && (n = {});
|
|
308
|
-
var r = h.call(this, e, t, n), i = e.getSelectionRange(), a = e.session.replace(i, r.text), o = new g(e), s = e.inVirtualSelectionMode && e.selection.index;
|
|
309
|
-
o.addTabstops(r.tabstops, i.start, a, s);
|
|
310
|
-
}, e.prototype.insertSnippet = function(e, t, n) {
|
|
311
|
-
n === void 0 && (n = {});
|
|
312
|
-
var r = this;
|
|
313
|
-
if (e.inVirtualSelectionMode) return r.insertSnippetForSelection(e, t, n);
|
|
314
|
-
e.forEachSelection(function() {
|
|
315
|
-
r.insertSnippetForSelection(e, t, n);
|
|
316
|
-
}, null, { keepOrder: !0 }), e.tabstopManager && e.tabstopManager.tabNext();
|
|
317
|
-
}, e.prototype.$getScope = function(e) {
|
|
318
|
-
var t = e.session.$mode.$id || "";
|
|
319
|
-
if (t = t.split("/").pop(), t === "html" || t === "php") {
|
|
320
|
-
t === "php" && !e.session.$mode.inlinePhp && (t = "html");
|
|
321
|
-
var n = e.getCursorPosition(), r = e.session.getState(n.row);
|
|
322
|
-
typeof r == "object" && (r = r[0]), r.substring && (r.substring(0, 3) == "js-" ? t = "javascript" : r.substring(0, 4) == "css-" ? t = "css" : r.substring(0, 4) == "php-" && (t = "php"));
|
|
323
|
-
}
|
|
324
|
-
return t;
|
|
325
|
-
}, e.prototype.getActiveScopes = function(e) {
|
|
326
|
-
var t = this.$getScope(e), n = [t], r = this.snippetMap;
|
|
327
|
-
return r[t] && r[t].includeScopes && n.push.apply(n, r[t].includeScopes), n.push("_"), n;
|
|
328
|
-
}, e.prototype.expandWithTab = function(e, t) {
|
|
329
|
-
var n = this, r = e.forEachSelection(function() {
|
|
330
|
-
return n.expandSnippetForSelection(e, t);
|
|
331
|
-
}, null, { keepOrder: !0 });
|
|
332
|
-
return r && e.tabstopManager && e.tabstopManager.tabNext(), r;
|
|
333
|
-
}, e.prototype.expandSnippetForSelection = function(e, t) {
|
|
334
|
-
var n = e.getCursorPosition(), r = e.session.getLine(n.row), i = r.substring(0, n.column), a = r.substr(n.column), o = this.snippetMap, s;
|
|
335
|
-
return this.getActiveScopes(e).some(function(e) {
|
|
336
|
-
var t = o[e];
|
|
337
|
-
return t && (s = this.findMatchingSnippet(t, i, a)), !!s;
|
|
338
|
-
}, this), s ? t && t.dryRun ? !0 : (e.session.doc.removeInLine(n.row, n.column - s.replaceBefore.length, n.column + s.replaceAfter.length), this.variables.M__ = s.matchBefore, this.variables.T__ = s.matchAfter, this.insertSnippetForSelection(e, s.content), this.variables.M__ = this.variables.T__ = null, !0) : !1;
|
|
339
|
-
}, e.prototype.findMatchingSnippet = function(e, t, n) {
|
|
340
|
-
for (var r = e.length; r--;) {
|
|
341
|
-
var i = e[r];
|
|
342
|
-
if ((!i.startRe || i.startRe.test(t)) && (!i.endRe || i.endRe.test(n)) && (i.startRe || i.endRe)) return i.matchBefore = i.startRe ? i.startRe.exec(t) : [""], i.matchAfter = i.endRe ? i.endRe.exec(n) : [""], i.replaceBefore = i.triggerRe ? i.triggerRe.exec(t)[0] : "", i.replaceAfter = i.endTriggerRe ? i.endTriggerRe.exec(n)[0] : "", i;
|
|
343
|
-
}
|
|
344
|
-
}, e.prototype.register = function(e, t) {
|
|
345
|
-
var n = this.snippetMap, r = this.snippetNameMap, i = this;
|
|
346
|
-
e ||= [];
|
|
347
|
-
function a(e) {
|
|
348
|
-
return e && !/^\^?\(.*\)\$?$|^\\b$/.test(e) && (e = "(?:" + e + ")"), e || "";
|
|
349
|
-
}
|
|
350
|
-
function s(e, t, n) {
|
|
351
|
-
return e = a(e), t = a(t), n ? (e = t + e, e && e[e.length - 1] != "$" && (e += "$")) : (e += t, e && e[0] != "^" && (e = "^" + e)), new RegExp(e);
|
|
352
|
-
}
|
|
353
|
-
function c(e) {
|
|
354
|
-
e.scope ||= t || "_", t = e.scope, n[t] || (n[t] = [], r[t] = {});
|
|
355
|
-
var a = r[t];
|
|
356
|
-
if (e.name) {
|
|
357
|
-
var c = a[e.name];
|
|
358
|
-
c && i.unregister(c), a[e.name] = e;
|
|
359
|
-
}
|
|
360
|
-
n[t].push(e), e.prefix && (e.tabTrigger = e.prefix), !e.content && e.body && (e.content = Array.isArray(e.body) ? e.body.join("\n") : e.body), e.tabTrigger && !e.trigger && (!e.guard && /^\w/.test(e.tabTrigger) && (e.guard = "\\b"), e.trigger = o.escapeRegExp(e.tabTrigger)), (e.trigger || e.guard || e.endTrigger || e.endGuard) && (e.startRe = s(e.trigger, e.guard, !0), e.triggerRe = new RegExp(e.trigger), e.endRe = s(e.endTrigger, e.endGuard, !0), e.endTriggerRe = new RegExp(e.endTrigger));
|
|
361
|
-
}
|
|
362
|
-
Array.isArray(e) ? e.forEach(c) : Object.keys(e).forEach(function(t) {
|
|
363
|
-
c(e[t]);
|
|
364
|
-
}), this._signal("registerSnippets", { scope: t });
|
|
365
|
-
}, e.prototype.unregister = function(e, t) {
|
|
366
|
-
var n = this.snippetMap, r = this.snippetNameMap;
|
|
367
|
-
function i(e) {
|
|
368
|
-
var i = r[e.scope || t];
|
|
369
|
-
if (i && i[e.name]) {
|
|
370
|
-
delete i[e.name];
|
|
371
|
-
var a = n[e.scope || t], o = a && a.indexOf(e);
|
|
372
|
-
o >= 0 && a.splice(o, 1);
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
e.content ? i(e) : Array.isArray(e) && e.forEach(i);
|
|
376
|
-
}, e.prototype.parseSnippetFile = function(e) {
|
|
377
|
-
e = e.replace(/\r/g, "");
|
|
378
|
-
for (var t = [], n = {}, r = /^#.*|^({[\s\S]*})\s*$|^(\S+) (.*)$|^((?:\n*\t.*)+)/gm, i; i = r.exec(e);) {
|
|
379
|
-
if (i[1]) try {
|
|
380
|
-
n = JSON.parse(i[1]), t.push(n);
|
|
381
|
-
} catch {}
|
|
382
|
-
if (i[4]) n.content = i[4].replace(/^\t/gm, ""), t.push(n), n = {};
|
|
383
|
-
else {
|
|
384
|
-
var a = i[2], o = i[3];
|
|
385
|
-
if (a == "regex") {
|
|
386
|
-
var s = /\/((?:[^\/\\]|\\.)*)|$/g;
|
|
387
|
-
n.guard = s.exec(o)[1], n.trigger = s.exec(o)[1], n.endTrigger = s.exec(o)[1], n.endGuard = s.exec(o)[1];
|
|
388
|
-
} else a == "snippet" ? (n.tabTrigger = o.match(/^\S*/)[0], n.name || (n.name = o)) : a && (n[a] = o);
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
return t;
|
|
392
|
-
}, e.prototype.getSnippetByName = function(e, t) {
|
|
393
|
-
var n = this.snippetNameMap, r;
|
|
394
|
-
return this.getActiveScopes(t).some(function(t) {
|
|
395
|
-
var i = n[t];
|
|
396
|
-
return i && (r = i[e]), !!r;
|
|
397
|
-
}, this), r;
|
|
398
|
-
}, e;
|
|
399
|
-
}();
|
|
400
|
-
i.implement(m.prototype, a);
|
|
401
|
-
var h = function(e, t, n) {
|
|
402
|
-
n === void 0 && (n = {});
|
|
403
|
-
var r = e.getCursorPosition(), i = e.session.getLine(r.row), a = e.session.getTabString(), o = i.match(/^\s*/)[0];
|
|
404
|
-
r.column < o.length && (o = o.slice(0, r.column)), t = t.replace(/\r/g, "");
|
|
405
|
-
var s = this.tokenizeTmSnippet(t);
|
|
406
|
-
s = this.resolveVariables(s, e), s = s.map(function(e) {
|
|
407
|
-
return e == "\n" && !n.excludeExtraIndent ? e + o : typeof e == "string" ? e.replace(/\t/g, a) : e;
|
|
408
|
-
});
|
|
409
|
-
var c = [];
|
|
410
|
-
s.forEach(function(e, t) {
|
|
411
|
-
if (typeof e == "object") {
|
|
412
|
-
var n = e.tabstopId, r = c[n];
|
|
413
|
-
if (r || (r = c[n] = [], r.index = n, r.value = "", r.parents = {}), r.indexOf(e) === -1) {
|
|
414
|
-
e.choices && !r.choices && (r.choices = e.choices), r.push(e);
|
|
415
|
-
var i = s.indexOf(e, t + 1);
|
|
416
|
-
if (i !== -1) {
|
|
417
|
-
var a = s.slice(t + 1, i);
|
|
418
|
-
a.some(function(e) {
|
|
419
|
-
return typeof e == "object";
|
|
420
|
-
}) && !r.value ? r.value = a : a.length && (!r.value || typeof r.value != "string") && (r.value = a.join(""));
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
}), c.forEach(function(e) {
|
|
425
|
-
e.length = 0;
|
|
426
|
-
});
|
|
427
|
-
var l = {};
|
|
428
|
-
function u(e) {
|
|
429
|
-
for (var t = [], n = 0; n < e.length; n++) {
|
|
430
|
-
var r = e[n];
|
|
431
|
-
if (typeof r == "object") {
|
|
432
|
-
if (l[r.tabstopId]) continue;
|
|
433
|
-
r = t[e.lastIndexOf(r, n - 1)] || { tabstopId: r.tabstopId };
|
|
434
|
-
}
|
|
435
|
-
t[n] = r;
|
|
436
|
-
}
|
|
437
|
-
return t;
|
|
438
|
-
}
|
|
439
|
-
for (var d = 0; d < s.length; d++) {
|
|
440
|
-
var f = s[d];
|
|
441
|
-
if (typeof f == "object") {
|
|
442
|
-
var p = f.tabstopId, m = c[p], h = s.indexOf(f, d + 1);
|
|
443
|
-
if (l[p]) {
|
|
444
|
-
l[p] === f && (delete l[p], Object.keys(l).forEach(function(e) {
|
|
445
|
-
m.parents[e] = !0;
|
|
446
|
-
}));
|
|
447
|
-
continue;
|
|
448
|
-
}
|
|
449
|
-
l[p] = f;
|
|
450
|
-
var g = m.value;
|
|
451
|
-
typeof g == "string" ? f.fmt && (g = this.tmStrFormat(g, f, e)) : g = u(g), s.splice.apply(s, [d + 1, Math.max(0, h - d)].concat(g, f)), m.indexOf(f) === -1 && m.push(f);
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
var _ = 0, v = 0, y = "";
|
|
455
|
-
return s.forEach(function(e) {
|
|
456
|
-
if (typeof e == "string") {
|
|
457
|
-
var t = e.split("\n");
|
|
458
|
-
t.length > 1 ? (v = t[t.length - 1].length, _ += t.length - 1) : v += e.length, y += e;
|
|
459
|
-
} else e && (e.start ? e.end = {
|
|
460
|
-
row: _,
|
|
461
|
-
column: v
|
|
462
|
-
} : e.start = {
|
|
463
|
-
row: _,
|
|
464
|
-
column: v
|
|
465
|
-
});
|
|
466
|
-
}), {
|
|
467
|
-
text: y,
|
|
468
|
-
tabstops: c,
|
|
469
|
-
tokens: s
|
|
470
|
-
};
|
|
471
|
-
}, g = function() {
|
|
472
|
-
function e(e) {
|
|
473
|
-
if (this.index = 0, this.ranges = [], this.tabstops = [], e.tabstopManager) return e.tabstopManager;
|
|
474
|
-
e.tabstopManager = this, this.$onChange = this.onChange.bind(this), this.$onChangeSelection = o.delayedCall(this.onChangeSelection.bind(this)).schedule, this.$onChangeSession = this.onChangeSession.bind(this), this.$onAfterExec = this.onAfterExec.bind(this), this.attach(e);
|
|
475
|
-
}
|
|
476
|
-
return e.prototype.attach = function(e) {
|
|
477
|
-
this.$openTabstops = null, this.selectedTabstop = null, this.editor = e, this.session = e.session, this.editor.on("change", this.$onChange), this.editor.on("changeSelection", this.$onChangeSelection), this.editor.on("changeSession", this.$onChangeSession), this.editor.commands.on("afterExec", this.$onAfterExec), this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler);
|
|
478
|
-
}, e.prototype.detach = function() {
|
|
479
|
-
this.tabstops.forEach(this.removeTabstopMarkers, this), this.ranges.length = 0, this.tabstops.length = 0, this.selectedTabstop = null, this.editor.off("change", this.$onChange), this.editor.off("changeSelection", this.$onChangeSelection), this.editor.off("changeSession", this.$onChangeSession), this.editor.commands.off("afterExec", this.$onAfterExec), this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler), this.editor.tabstopManager = null, this.session = null, this.editor = null;
|
|
480
|
-
}, e.prototype.onChange = function(e) {
|
|
481
|
-
for (var t = e.action[0] == "r", n = this.selectedTabstop || {}, r = n.parents || {}, i = this.tabstops.slice(), a = 0; a < i.length; a++) {
|
|
482
|
-
var o = i[a], s = o == n || r[o.index];
|
|
483
|
-
if (o.rangeList.$bias = +!s, e.action == "remove" && o !== n) {
|
|
484
|
-
var c = o.parents && o.parents[n.index], l = o.rangeList.pointIndex(e.start, c);
|
|
485
|
-
l = l < 0 ? -l - 1 : l + 1;
|
|
486
|
-
var u = o.rangeList.pointIndex(e.end, c);
|
|
487
|
-
u = u < 0 ? -u - 1 : u - 1;
|
|
488
|
-
for (var d = o.rangeList.ranges.slice(l, u), f = 0; f < d.length; f++) this.removeRange(d[f]);
|
|
489
|
-
}
|
|
490
|
-
o.rangeList.$onChange(e);
|
|
491
|
-
}
|
|
492
|
-
var p = this.session;
|
|
493
|
-
!this.$inChange && t && p.getLength() == 1 && !p.getValue() && this.detach();
|
|
494
|
-
}, e.prototype.updateLinkedFields = function() {
|
|
495
|
-
var e = this.selectedTabstop;
|
|
496
|
-
if (e && e.hasLinkedRanges && e.firstNonLinked) {
|
|
497
|
-
this.$inChange = !0;
|
|
498
|
-
for (var n = this.session, r = n.getTextRange(e.firstNonLinked), i = 0; i < e.length; i++) {
|
|
499
|
-
var a = e[i];
|
|
500
|
-
if (a.linked) {
|
|
501
|
-
var o = a.original, s = t.snippetManager.tmStrFormat(r, o, this.editor);
|
|
502
|
-
n.replace(a, s);
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
this.$inChange = !1;
|
|
506
|
-
}
|
|
507
|
-
}, e.prototype.onAfterExec = function(e) {
|
|
508
|
-
e.command && !e.command.readOnly && this.updateLinkedFields();
|
|
509
|
-
}, e.prototype.onChangeSelection = function() {
|
|
510
|
-
if (this.editor) {
|
|
511
|
-
for (var e = this.editor.selection.lead, t = this.editor.selection.anchor, n = this.editor.selection.isEmpty(), r = 0; r < this.ranges.length; r++) if (!this.ranges[r].linked) {
|
|
512
|
-
var i = this.ranges[r].contains(e.row, e.column), a = n || this.ranges[r].contains(t.row, t.column);
|
|
513
|
-
if (i && a) return;
|
|
514
|
-
}
|
|
515
|
-
this.detach();
|
|
516
|
-
}
|
|
517
|
-
}, e.prototype.onChangeSession = function() {
|
|
518
|
-
this.detach();
|
|
519
|
-
}, e.prototype.tabNext = function(e) {
|
|
520
|
-
var t = this.tabstops.length, n = this.index + (e || 1);
|
|
521
|
-
n = Math.min(Math.max(n, 1), t), n == t && (n = 0), this.selectTabstop(n), this.updateTabstopMarkers(), n === 0 && this.detach();
|
|
522
|
-
}, e.prototype.selectTabstop = function(e) {
|
|
523
|
-
this.$openTabstops = null;
|
|
524
|
-
var t = this.tabstops[this.index];
|
|
525
|
-
if (t && this.addTabstopMarkers(t), this.index = e, t = this.tabstops[this.index], t && t.length) {
|
|
526
|
-
this.selectedTabstop = t;
|
|
527
|
-
var n = t.firstNonLinked || t;
|
|
528
|
-
if (t.choices && (n.cursor = n.start), this.editor.inVirtualSelectionMode) this.editor.selection.fromOrientedRange(n);
|
|
529
|
-
else {
|
|
530
|
-
var r = this.editor.multiSelect;
|
|
531
|
-
r.toSingleRange(n);
|
|
532
|
-
for (var i = 0; i < t.length; i++) t.hasLinkedRanges && t[i].linked || r.addRange(t[i].clone(), !0);
|
|
533
|
-
}
|
|
534
|
-
this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler), this.selectedTabstop && this.selectedTabstop.choices && this.editor.execCommand("startAutocomplete", { matches: this.selectedTabstop.choices });
|
|
535
|
-
}
|
|
536
|
-
}, e.prototype.addTabstops = function(e, t, n) {
|
|
537
|
-
var r = this.useLink || !this.editor.getOption("enableMultiselect");
|
|
538
|
-
if (this.$openTabstops ||= [], !e[0]) {
|
|
539
|
-
var i = s.fromPoints(n, n);
|
|
540
|
-
v(i.start, t), v(i.end, t), e[0] = [i], e[0].index = 0;
|
|
541
|
-
}
|
|
542
|
-
var a = [this.index + 1, 0], o = this.ranges, l = this.snippetId = (this.snippetId || 0) + 1;
|
|
543
|
-
e.forEach(function(e, n) {
|
|
544
|
-
var i = this.$openTabstops[n] || e;
|
|
545
|
-
i.snippetId = l;
|
|
546
|
-
for (var u = 0; u < e.length; u++) {
|
|
547
|
-
var d = e[u], f = s.fromPoints(d.start, d.end || d.start);
|
|
548
|
-
_(f.start, t), _(f.end, t), f.original = d, f.tabstop = i, o.push(f), i == e ? i[u] = f : i.unshift(f), d.fmtString || i.firstNonLinked && r ? (f.linked = !0, i.hasLinkedRanges = !0) : i.firstNonLinked ||= f;
|
|
549
|
-
}
|
|
550
|
-
i.firstNonLinked || (i.hasLinkedRanges = !1), i === e && (a.push(i), this.$openTabstops[n] = i), this.addTabstopMarkers(i), i.rangeList = i.rangeList || new c(), i.rangeList.$bias = 0, i.rangeList.addList(i);
|
|
551
|
-
}, this), a.length > 2 && (this.tabstops.length && a.push(a.splice(2, 1)[0]), this.tabstops.splice.apply(this.tabstops, a));
|
|
552
|
-
}, e.prototype.addTabstopMarkers = function(e) {
|
|
553
|
-
var t = this.session;
|
|
554
|
-
e.forEach(function(e) {
|
|
555
|
-
e.markerId ||= t.addMarker(e, "ace_snippet-marker", "text");
|
|
556
|
-
});
|
|
557
|
-
}, e.prototype.removeTabstopMarkers = function(e) {
|
|
558
|
-
var t = this.session;
|
|
559
|
-
e.forEach(function(e) {
|
|
560
|
-
t.removeMarker(e.markerId), e.markerId = null;
|
|
561
|
-
});
|
|
562
|
-
}, e.prototype.updateTabstopMarkers = function() {
|
|
563
|
-
if (this.selectedTabstop) {
|
|
564
|
-
var e = this.selectedTabstop.snippetId;
|
|
565
|
-
this.selectedTabstop.index === 0 && e--, this.tabstops.forEach(function(t) {
|
|
566
|
-
t.snippetId === e ? this.addTabstopMarkers(t) : this.removeTabstopMarkers(t);
|
|
567
|
-
}, this);
|
|
568
|
-
}
|
|
569
|
-
}, e.prototype.removeRange = function(e) {
|
|
570
|
-
var t = e.tabstop.indexOf(e);
|
|
571
|
-
t != -1 && e.tabstop.splice(t, 1), t = this.ranges.indexOf(e), t != -1 && this.ranges.splice(t, 1), t = e.tabstop.rangeList.ranges.indexOf(e), t != -1 && e.tabstop.splice(t, 1), this.session.removeMarker(e.markerId), e.tabstop.length || (t = this.tabstops.indexOf(e.tabstop), t != -1 && this.tabstops.splice(t, 1), this.tabstops.length || this.detach());
|
|
572
|
-
}, e;
|
|
573
|
-
}();
|
|
574
|
-
g.prototype.keyboardHandler = new l(), g.prototype.keyboardHandler.bindKeys({
|
|
575
|
-
Tab: function(e) {
|
|
576
|
-
t.snippetManager && t.snippetManager.expandWithTab(e) || (e.tabstopManager.tabNext(1), e.renderer.scrollCursorIntoView());
|
|
577
|
-
},
|
|
578
|
-
"Shift-Tab": function(e) {
|
|
579
|
-
e.tabstopManager.tabNext(-1), e.renderer.scrollCursorIntoView();
|
|
580
|
-
},
|
|
581
|
-
Esc: function(e) {
|
|
582
|
-
e.tabstopManager.detach();
|
|
583
|
-
}
|
|
584
|
-
});
|
|
585
|
-
var _ = function(e, t) {
|
|
586
|
-
e.row == 0 && (e.column += t.column), e.row += t.row;
|
|
587
|
-
}, v = function(e, t) {
|
|
588
|
-
e.row == t.row && (e.column -= t.column), e.row -= t.row;
|
|
589
|
-
};
|
|
590
|
-
r.importCssString("\n.ace_snippet-marker {\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n background: rgba(194, 193, 208, 0.09);\n border: 1px dotted rgba(211, 208, 235, 0.62);\n position: absolute;\n}", "snippets.css", !1), t.snippetManager = new m();
|
|
591
|
-
var y = e("./editor").Editor;
|
|
592
|
-
(function() {
|
|
593
|
-
this.insertSnippet = function(e, n) {
|
|
594
|
-
return t.snippetManager.insertSnippet(this, e, n);
|
|
595
|
-
}, this.expandSnippet = function(e) {
|
|
596
|
-
return t.snippetManager.expandWithTab(this, e);
|
|
597
|
-
};
|
|
598
|
-
}).call(y.prototype);
|
|
599
|
-
}), ace.define("ace/autocomplete/popup", [
|
|
600
|
-
"require",
|
|
601
|
-
"exports",
|
|
602
|
-
"module",
|
|
603
|
-
"ace/virtual_renderer",
|
|
604
|
-
"ace/editor",
|
|
605
|
-
"ace/range",
|
|
606
|
-
"ace/lib/event",
|
|
607
|
-
"ace/lib/lang",
|
|
608
|
-
"ace/lib/dom",
|
|
609
|
-
"ace/config",
|
|
610
|
-
"ace/lib/useragent"
|
|
611
|
-
], function(e, t, n) {
|
|
612
|
-
var r = e("../virtual_renderer").VirtualRenderer, i = e("../editor").Editor, a = e("../range").Range, o = e("../lib/event"), s = e("../lib/lang"), c = e("../lib/dom"), l = e("../config").nls, u = e("./../lib/useragent"), d = function(e) {
|
|
613
|
-
return `suggest-aria-id:${e}`;
|
|
614
|
-
}, f = u.isSafari ? "menu" : "listbox", p = u.isSafari ? "menuitem" : "option", m = u.isSafari ? "aria-current" : "aria-selected", h = function(e) {
|
|
615
|
-
var t = new r(e);
|
|
616
|
-
t.$maxLines = 4;
|
|
617
|
-
var n = new i(t);
|
|
618
|
-
return n.setHighlightActiveLine(!1), n.setShowPrintMargin(!1), n.renderer.setShowGutter(!1), n.renderer.setHighlightGutterLine(!1), n.$mouseHandler.$focusTimeout = 0, n.$highlightTagPending = !0, n;
|
|
619
|
-
}, g = function() {
|
|
620
|
-
function e(e) {
|
|
621
|
-
var t = c.createElement("div"), n = h(t);
|
|
622
|
-
e && e.appendChild(t), t.style.display = "none", n.renderer.content.style.cursor = "default", n.renderer.setStyle("ace_autocomplete"), n.renderer.$textLayer.element.setAttribute("role", f), n.renderer.$textLayer.element.setAttribute("aria-roledescription", l("autocomplete.popup.aria-roledescription", "Autocomplete suggestions")), n.renderer.$textLayer.element.setAttribute("aria-label", l("autocomplete.popup.aria-label", "Autocomplete suggestions")), n.renderer.textarea.setAttribute("aria-hidden", "true"), n.setOption("displayIndentGuides", !1), n.setOption("dragDelay", 150);
|
|
623
|
-
var r = function() {};
|
|
624
|
-
n.focus = r, n.$isFocused = !0, n.renderer.$cursorLayer.restartTimer = r, n.renderer.$cursorLayer.element.style.opacity = "0", n.renderer.$maxLines = 8, n.renderer.$keepTextAreaAtCursor = !1, n.setHighlightActiveLine(!1), n.session.highlight(""), n.session.$searchHighlight.clazz = "ace_highlight-marker", n.on("mousedown", function(e) {
|
|
625
|
-
var t = e.getDocumentPosition();
|
|
626
|
-
n.selection.moveToPosition(t), g.start.row = g.end.row = t.row, e.stop();
|
|
627
|
-
});
|
|
628
|
-
var i, u = new a(-1, 0, -1, Infinity), g = new a(-1, 0, -1, Infinity);
|
|
629
|
-
g.id = n.session.addMarker(g, "ace_active-line", "fullLine"), n.setSelectOnHover = function(e) {
|
|
630
|
-
e ? u.id &&= (n.session.removeMarker(u.id), null) : u.id = n.session.addMarker(u, "ace_line-hover", "fullLine");
|
|
631
|
-
}, n.setSelectOnHover(!1), n.on("mousemove", function(e) {
|
|
632
|
-
if (!i) {
|
|
633
|
-
i = e;
|
|
634
|
-
return;
|
|
635
|
-
}
|
|
636
|
-
if (i.x != e.x || i.y != e.y) {
|
|
637
|
-
i = e, i.scrollTop = n.renderer.scrollTop, n.isMouseOver = !0;
|
|
638
|
-
var t = i.getDocumentPosition().row;
|
|
639
|
-
u.start.row != t && (u.id || n.setRow(t), v(t));
|
|
640
|
-
}
|
|
641
|
-
}), n.renderer.on("beforeRender", function() {
|
|
642
|
-
if (i && u.start.row != -1) {
|
|
643
|
-
i.$pos = null;
|
|
644
|
-
var e = i.getDocumentPosition().row;
|
|
645
|
-
u.id || n.setRow(e), v(e, !0);
|
|
646
|
-
}
|
|
647
|
-
}), n.renderer.on("afterRender", function() {
|
|
648
|
-
for (var e = n.renderer.$textLayer, t = e.config.firstRow, r = e.config.lastRow; t <= r; t++) {
|
|
649
|
-
var i = e.element.childNodes[t - e.config.firstRow];
|
|
650
|
-
i.setAttribute("role", p), i.setAttribute("aria-roledescription", l("autocomplete.popup.item.aria-roledescription", "item")), i.setAttribute("aria-setsize", n.data.length), i.setAttribute("aria-describedby", "doc-tooltip"), i.setAttribute("aria-posinset", t + 1);
|
|
651
|
-
var a = n.getData(t);
|
|
652
|
-
if (a) {
|
|
653
|
-
var o = `${a.caption || a.value}${a.meta ? `, ${a.meta}` : ""}`;
|
|
654
|
-
i.setAttribute("aria-label", o);
|
|
655
|
-
}
|
|
656
|
-
i.querySelectorAll(".ace_completion-highlight").forEach(function(e) {
|
|
657
|
-
e.setAttribute("role", "mark");
|
|
658
|
-
});
|
|
659
|
-
}
|
|
660
|
-
}), n.renderer.on("afterRender", function() {
|
|
661
|
-
var e = n.getRow(), t = n.renderer.$textLayer, r = t.element.childNodes[e - t.config.firstRow], i = document.activeElement;
|
|
662
|
-
if (r !== n.selectedNode && n.selectedNode && (c.removeCssClass(n.selectedNode, "ace_selected"), n.selectedNode.removeAttribute(m), n.selectedNode.removeAttribute("id")), i.removeAttribute("aria-activedescendant"), n.selectedNode = r, r) {
|
|
663
|
-
var a = d(e);
|
|
664
|
-
c.addCssClass(r, "ace_selected"), r.id = a, t.element.setAttribute("aria-activedescendant", a), i.setAttribute("aria-activedescendant", a), r.setAttribute(m, "true");
|
|
665
|
-
}
|
|
666
|
-
});
|
|
667
|
-
var _ = function() {
|
|
668
|
-
v(-1);
|
|
669
|
-
}, v = function(e, t) {
|
|
670
|
-
e !== u.start.row && (u.start.row = u.end.row = e, t || n.session._emit("changeBackMarker"), n._emit("changeHoverMarker"));
|
|
671
|
-
};
|
|
672
|
-
n.getHoveredRow = function() {
|
|
673
|
-
return u.start.row;
|
|
674
|
-
}, o.addListener(n.container, "mouseout", function() {
|
|
675
|
-
n.isMouseOver = !1, _();
|
|
676
|
-
}), n.on("hide", _), n.on("changeSelection", _), n.session.doc.getLength = function() {
|
|
677
|
-
return n.data.length;
|
|
678
|
-
}, n.session.doc.getLine = function(e) {
|
|
679
|
-
var t = n.data[e];
|
|
680
|
-
return typeof t == "string" ? t : t && t.value || "";
|
|
681
|
-
};
|
|
682
|
-
var y = n.session.bgTokenizer;
|
|
683
|
-
return y.$tokenizeRow = function(e) {
|
|
684
|
-
var t = n.data[e], r = [];
|
|
685
|
-
if (!t) return r;
|
|
686
|
-
typeof t == "string" && (t = { value: t });
|
|
687
|
-
var i = t.caption || t.value || t.name;
|
|
688
|
-
function a(e, n) {
|
|
689
|
-
e && r.push({
|
|
690
|
-
type: (t.className || "") + (n || ""),
|
|
691
|
-
value: e
|
|
692
|
-
});
|
|
693
|
-
}
|
|
694
|
-
for (var o = i.toLowerCase(), s = (n.filterText || "").toLowerCase(), c = 0, l = 0, u = 0; u <= s.length; u++) if (u != l && (t.matchMask & 1 << u || u == s.length)) {
|
|
695
|
-
var d = s.slice(l, u);
|
|
696
|
-
l = u;
|
|
697
|
-
var f = o.indexOf(d, c);
|
|
698
|
-
if (f == -1) continue;
|
|
699
|
-
a(i.slice(c, f), ""), c = f + d.length, a(i.slice(f, c), "completion-highlight");
|
|
700
|
-
}
|
|
701
|
-
return a(i.slice(c, i.length), ""), r.push({
|
|
702
|
-
type: "completion-spacer",
|
|
703
|
-
value: " "
|
|
704
|
-
}), t.meta && r.push({
|
|
705
|
-
type: "completion-meta",
|
|
706
|
-
value: t.meta
|
|
707
|
-
}), t.message && r.push({
|
|
708
|
-
type: "completion-message",
|
|
709
|
-
value: t.message
|
|
710
|
-
}), r;
|
|
711
|
-
}, y.$updateOnChange = r, y.start = r, n.session.$computeWidth = function() {
|
|
712
|
-
return this.screenWidth = 0;
|
|
713
|
-
}, n.isOpen = !1, n.isTopdown = !1, n.autoSelect = !0, n.filterText = "", n.isMouseOver = !1, n.data = [], n.setData = function(e, t) {
|
|
714
|
-
n.filterText = t || "", n.setValue(s.stringRepeat("\n", e.length), -1), n.data = e || [], n.setRow(0);
|
|
715
|
-
}, n.getData = function(e) {
|
|
716
|
-
return n.data[e];
|
|
717
|
-
}, n.getRow = function() {
|
|
718
|
-
return g.start.row;
|
|
719
|
-
}, n.setRow = function(e) {
|
|
720
|
-
e = Math.max(this.autoSelect ? 0 : -1, Math.min(this.data.length - 1, e)), g.start.row != e && (n.selection.clearSelection(), g.start.row = g.end.row = e || 0, n.session._emit("changeBackMarker"), n.moveCursorTo(e || 0, 0), n.isOpen && n._signal("select"));
|
|
721
|
-
}, n.on("changeSelection", function() {
|
|
722
|
-
n.isOpen && n.setRow(n.selection.lead.row), n.renderer.scrollCursorIntoView();
|
|
723
|
-
}), n.hide = function() {
|
|
724
|
-
this.container.style.display = "none", n.anchorPos = null, n.anchor = null, n.isOpen && (n.isOpen = !1, this._signal("hide"));
|
|
725
|
-
}, n.tryShow = function(e, t, r, a) {
|
|
726
|
-
if (!a && n.isOpen && n.anchorPos && n.anchor && n.anchorPos.top === e.top && n.anchorPos.left === e.left && n.anchor === r) return !0;
|
|
727
|
-
var o = this.container, s = this.renderer.scrollBar.width || 10, l = window.innerHeight - s, u = window.innerWidth - s, d = this.renderer, f = d.$maxLines * t * 1.4, p = {
|
|
728
|
-
top: 0,
|
|
729
|
-
bottom: 0,
|
|
730
|
-
left: 0
|
|
731
|
-
}, m = l - e.top - 3 * this.$borderSize - t, h = e.top - 3 * this.$borderSize;
|
|
732
|
-
r ||= h <= m || m >= f ? "bottom" : "top", r === "top" ? (p.bottom = e.top - this.$borderSize, p.top = p.bottom - f) : r === "bottom" && (p.top = e.top + t + this.$borderSize, p.bottom = p.top + f);
|
|
733
|
-
var g = p.top >= 0 && p.bottom <= l;
|
|
734
|
-
if (!a && !g) return !1;
|
|
735
|
-
d.$maxPixelHeight = g ? null : r === "top" ? h : m, r === "top" ? (o.style.top = "", o.style.bottom = l + s - p.bottom + "px", n.isTopdown = !1) : (o.style.top = p.top + "px", o.style.bottom = "", n.isTopdown = !0), o.style.display = "";
|
|
736
|
-
var _ = e.left;
|
|
737
|
-
return _ + o.offsetWidth > u && (_ = u - o.offsetWidth), o.style.left = _ + "px", o.style.right = "", c.$fixPositionBug(o), n.isOpen || (n.isOpen = !0, this._signal("show"), i = null), n.anchorPos = e, n.anchor = r, !0;
|
|
738
|
-
}, n.show = function(e, t, n) {
|
|
739
|
-
this.tryShow(e, t, n ? "bottom" : void 0, !0);
|
|
740
|
-
}, n.goTo = function(e) {
|
|
741
|
-
var t = this.getRow(), n = this.session.getLength() - 1;
|
|
742
|
-
switch (e) {
|
|
743
|
-
case "up":
|
|
744
|
-
t = t <= 0 ? n : t - 1;
|
|
745
|
-
break;
|
|
746
|
-
case "down":
|
|
747
|
-
t = t >= n ? -1 : t + 1;
|
|
748
|
-
break;
|
|
749
|
-
case "start":
|
|
750
|
-
t = 0;
|
|
751
|
-
break;
|
|
752
|
-
case "end": t = n;
|
|
753
|
-
}
|
|
754
|
-
this.setRow(t);
|
|
755
|
-
}, n.getTextLeftOffset = function() {
|
|
756
|
-
return this.$borderSize + this.renderer.$padding + this.$imageSize;
|
|
757
|
-
}, n.$imageSize = 0, n.$borderSize = 1, n;
|
|
758
|
-
}
|
|
759
|
-
return e;
|
|
760
|
-
}();
|
|
761
|
-
c.importCssString("\n.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {\n background-color: #CAD6FA;\n z-index: 1;\n}\n.ace_dark.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {\n background-color: #3a674e;\n}\n.ace_editor.ace_autocomplete .ace_line-hover {\n border: 1px solid #abbffe;\n margin-top: -1px;\n background: rgba(233,233,253,0.4);\n position: absolute;\n z-index: 2;\n}\n.ace_dark.ace_editor.ace_autocomplete .ace_line-hover {\n border: 1px solid rgba(109, 150, 13, 0.8);\n background: rgba(58, 103, 78, 0.62);\n}\n.ace_completion-meta {\n opacity: 0.5;\n margin-left: 0.9em;\n}\n.ace_completion-message {\n margin-left: 0.9em;\n color: blue;\n}\n.ace_editor.ace_autocomplete .ace_completion-highlight{\n color: #2d69c7;\n}\n.ace_dark.ace_editor.ace_autocomplete .ace_completion-highlight{\n color: #93ca12;\n}\n.ace_editor.ace_autocomplete {\n width: 300px;\n z-index: 200000;\n border: 1px lightgray solid;\n position: fixed;\n box-shadow: 2px 3px 5px rgba(0,0,0,.2);\n line-height: 1.4;\n background: #fefefe;\n color: #111;\n}\n.ace_dark.ace_editor.ace_autocomplete {\n border: 1px #484747 solid;\n box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.51);\n line-height: 1.4;\n background: #25282c;\n color: #c1c1c1;\n}\n.ace_autocomplete .ace_text-layer {\n width: calc(100% - 8px);\n}\n.ace_autocomplete .ace_line {\n display: flex;\n align-items: center;\n}\n.ace_autocomplete .ace_line > * {\n min-width: 0;\n flex: 0 0 auto;\n}\n.ace_autocomplete .ace_line .ace_ {\n flex: 0 1 auto;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ace_autocomplete .ace_completion-spacer {\n flex: 1;\n}\n.ace_autocomplete.ace_loading:after {\n content: \"\";\n position: absolute;\n top: 0px;\n height: 2px;\n width: 8%;\n background: blue;\n z-index: 100;\n animation: ace_progress 3s infinite linear;\n animation-delay: 300ms;\n transform: translateX(-100%) scaleX(1);\n}\n@keyframes ace_progress {\n 0% { transform: translateX(-100%) scaleX(1) }\n 50% { transform: translateX(625%) scaleX(2) } \n 100% { transform: translateX(1500%) scaleX(3) } \n}\n@media (prefers-reduced-motion) {\n .ace_autocomplete.ace_loading:after {\n transform: translateX(625%) scaleX(2);\n animation: none;\n }\n}\n", "autocompletion.css", !1), t.AcePopup = g, t.$singleLineEditor = h, t.getAriaId = d;
|
|
762
|
-
}), ace.define("ace/autocomplete/inline_screenreader", [
|
|
763
|
-
"require",
|
|
764
|
-
"exports",
|
|
765
|
-
"module"
|
|
766
|
-
], function(e, t, n) {
|
|
767
|
-
t.AceInlineScreenReader = function() {
|
|
768
|
-
function e(e) {
|
|
769
|
-
this.editor = e, this.screenReaderDiv = document.createElement("div"), this.screenReaderDiv.classList.add("ace_screenreader-only"), this.editor.container.appendChild(this.screenReaderDiv);
|
|
770
|
-
}
|
|
771
|
-
return e.prototype.setScreenReaderContent = function(e) {
|
|
772
|
-
for (!this.popup && this.editor.completer && this.editor.completer.popup && (this.popup = this.editor.completer.popup, this.popup.renderer.on("afterRender", function() {
|
|
773
|
-
var e = this.popup.getRow(), t = this.popup.renderer.$textLayer, n = t.element.childNodes[e - t.config.firstRow];
|
|
774
|
-
if (n) {
|
|
775
|
-
for (var r = "doc-tooltip ", i = 0; i < this._lines.length; i++) r += `ace-inline-screenreader-line-${i} `;
|
|
776
|
-
n.setAttribute("aria-describedby", r);
|
|
777
|
-
}
|
|
778
|
-
}.bind(this))); this.screenReaderDiv.firstChild;) this.screenReaderDiv.removeChild(this.screenReaderDiv.firstChild);
|
|
779
|
-
this._lines = e.split(/\r\n|\r|\n/);
|
|
780
|
-
var t = this.createCodeBlock();
|
|
781
|
-
this.screenReaderDiv.appendChild(t);
|
|
782
|
-
}, e.prototype.destroy = function() {
|
|
783
|
-
this.screenReaderDiv.remove();
|
|
784
|
-
}, e.prototype.createCodeBlock = function() {
|
|
785
|
-
var e = document.createElement("pre");
|
|
786
|
-
e.setAttribute("id", "ace-inline-screenreader");
|
|
787
|
-
for (var t = 0; t < this._lines.length; t++) {
|
|
788
|
-
var n = document.createElement("code");
|
|
789
|
-
n.setAttribute("id", `ace-inline-screenreader-line-${t}`);
|
|
790
|
-
var r = document.createTextNode(this._lines[t]);
|
|
791
|
-
n.appendChild(r), e.appendChild(n);
|
|
792
|
-
}
|
|
793
|
-
return e;
|
|
794
|
-
}, e;
|
|
795
|
-
}();
|
|
796
|
-
}), ace.define("ace/autocomplete/inline", [
|
|
797
|
-
"require",
|
|
798
|
-
"exports",
|
|
799
|
-
"module",
|
|
800
|
-
"ace/snippets",
|
|
801
|
-
"ace/autocomplete/inline_screenreader"
|
|
802
|
-
], function(e, t, n) {
|
|
803
|
-
var r = e("../snippets").snippetManager, i = e("./inline_screenreader").AceInlineScreenReader;
|
|
804
|
-
t.AceInline = function() {
|
|
805
|
-
function e() {
|
|
806
|
-
this.editor = null;
|
|
807
|
-
}
|
|
808
|
-
return e.prototype.show = function(e, t, n) {
|
|
809
|
-
if (n ||= "", e && this.editor && this.editor !== e && (this.hide(), this.editor = null, this.inlineScreenReader = null), !e || !t) return !1;
|
|
810
|
-
this.inlineScreenReader ||= new i(e);
|
|
811
|
-
var a = t.snippet ? r.getDisplayTextForSnippet(e, t.snippet) : t.value;
|
|
812
|
-
return t.hideInlinePreview || !a || !a.startsWith(n) ? !1 : (this.editor = e, this.inlineScreenReader.setScreenReaderContent(a), a = a.slice(n.length), a === "" ? e.removeGhostText() : e.setGhostText(a), !0);
|
|
813
|
-
}, e.prototype.isOpen = function() {
|
|
814
|
-
return this.editor ? !!this.editor.renderer.$ghostText : !1;
|
|
815
|
-
}, e.prototype.hide = function() {
|
|
816
|
-
return this.editor ? (this.editor.removeGhostText(), !0) : !1;
|
|
817
|
-
}, e.prototype.destroy = function() {
|
|
818
|
-
this.hide(), this.editor = null, this.inlineScreenReader &&= (this.inlineScreenReader.destroy(), null);
|
|
819
|
-
}, e;
|
|
820
|
-
}();
|
|
821
|
-
}), ace.define("ace/autocomplete/util", [
|
|
822
|
-
"require",
|
|
823
|
-
"exports",
|
|
824
|
-
"module"
|
|
825
|
-
], function(e, t, n) {
|
|
826
|
-
t.parForEach = function(e, t, n) {
|
|
827
|
-
var r = 0, i = e.length;
|
|
828
|
-
i === 0 && n();
|
|
829
|
-
for (var a = 0; a < i; a++) t(e[a], function(e, t) {
|
|
830
|
-
r++, r === i && n(e, t);
|
|
831
|
-
});
|
|
832
|
-
};
|
|
833
|
-
var r = /[a-zA-Z_0-9\$\-\u00A2-\u2000\u2070-\uFFFF]/;
|
|
834
|
-
t.retrievePrecedingIdentifier = function(e, t, n) {
|
|
835
|
-
n ||= r;
|
|
836
|
-
for (var i = [], a = t - 1; a >= 0 && n.test(e[a]); a--) i.push(e[a]);
|
|
837
|
-
return i.reverse().join("");
|
|
838
|
-
}, t.retrieveFollowingIdentifier = function(e, t, n) {
|
|
839
|
-
n ||= r;
|
|
840
|
-
for (var i = [], a = t; a < e.length && n.test(e[a]); a++) i.push(e[a]);
|
|
841
|
-
return i;
|
|
842
|
-
}, t.getCompletionPrefix = function(e) {
|
|
843
|
-
var t = e.getCursorPosition(), n = e.session.getLine(t.row), r;
|
|
844
|
-
return e.completers.forEach(function(e) {
|
|
845
|
-
e.identifierRegexps && e.identifierRegexps.forEach(function(e) {
|
|
846
|
-
!r && e && (r = this.retrievePrecedingIdentifier(n, t.column, e));
|
|
847
|
-
}.bind(this));
|
|
848
|
-
}.bind(this)), r || this.retrievePrecedingIdentifier(n, t.column);
|
|
849
|
-
}, t.triggerAutocomplete = function(e, t) {
|
|
850
|
-
var t = t ?? e.session.getPrecedingCharacter();
|
|
851
|
-
return e.completers.some(function(e) {
|
|
852
|
-
if (e.triggerCharacters && Array.isArray(e.triggerCharacters)) return e.triggerCharacters.includes(t);
|
|
853
|
-
});
|
|
854
|
-
};
|
|
855
|
-
}), ace.define("ace/autocomplete", [
|
|
856
|
-
"require",
|
|
857
|
-
"exports",
|
|
858
|
-
"module",
|
|
859
|
-
"ace/keyboard/hash_handler",
|
|
860
|
-
"ace/autocomplete/popup",
|
|
861
|
-
"ace/autocomplete/inline",
|
|
862
|
-
"ace/autocomplete/popup",
|
|
863
|
-
"ace/autocomplete/util",
|
|
864
|
-
"ace/lib/lang",
|
|
865
|
-
"ace/lib/dom",
|
|
866
|
-
"ace/snippets",
|
|
867
|
-
"ace/config",
|
|
868
|
-
"ace/lib/event",
|
|
869
|
-
"ace/lib/scroll"
|
|
870
|
-
], function(e, t, n) {
|
|
871
|
-
var r = e("./keyboard/hash_handler").HashHandler, i = e("./autocomplete/popup").AcePopup, a = e("./autocomplete/inline").AceInline, o = e("./autocomplete/popup").getAriaId, s = e("./autocomplete/util"), c = e("./lib/lang"), l = e("./lib/dom"), u = e("./snippets").snippetManager, d = e("./config"), f = e("./lib/event"), p = e("./lib/scroll").preventParentScroll, m = function(e, t) {
|
|
872
|
-
t.completer && t.completer.destroy();
|
|
873
|
-
}, h = function() {
|
|
874
|
-
function e() {
|
|
875
|
-
this.autoInsert = !1, this.autoSelect = !0, this.autoShown = !1, this.exactMatch = !1, this.inlineEnabled = !1, this.keyboardHandler = new r(), this.keyboardHandler.bindKeys(this.commands), this.parentNode = null, this.setSelectOnHover = !1, this.hasSeen = /* @__PURE__ */ new Set(), this.showLoadingState = !1, this.stickySelectionDelay = 500, this.blurListener = this.blurListener.bind(this), this.changeListener = this.changeListener.bind(this), this.mousedownListener = this.mousedownListener.bind(this), this.mousewheelListener = this.mousewheelListener.bind(this), this.onLayoutChange = this.onLayoutChange.bind(this), this.changeTimer = c.delayedCall(function() {
|
|
876
|
-
this.updateCompletions(!0);
|
|
877
|
-
}.bind(this)), this.tooltipTimer = c.delayedCall(this.updateDocTooltip.bind(this), 50), this.popupTimer = c.delayedCall(this.$updatePopupPosition.bind(this), 50), this.stickySelectionTimer = c.delayedCall(function() {
|
|
878
|
-
this.stickySelection = !0;
|
|
879
|
-
}.bind(this), this.stickySelectionDelay), this.$firstOpenTimer = c.delayedCall(function() {
|
|
880
|
-
var t = this.completionProvider && this.completionProvider.initialPosition;
|
|
881
|
-
this.autoShown || this.popup && this.popup.isOpen || !t || this.editor.completers.length === 0 || (this.completions = new _(e.completionsForLoading), this.openPopup(this.editor, t.prefix, !1), this.popup.renderer.setStyle("ace_loading", !0));
|
|
882
|
-
}.bind(this), this.stickySelectionDelay);
|
|
883
|
-
}
|
|
884
|
-
return Object.defineProperty(e, "completionsForLoading", {
|
|
885
|
-
get: function() {
|
|
886
|
-
return [{
|
|
887
|
-
caption: d.nls("autocomplete.loading", "Loading..."),
|
|
888
|
-
value: ""
|
|
889
|
-
}];
|
|
890
|
-
},
|
|
891
|
-
enumerable: !1,
|
|
892
|
-
configurable: !0
|
|
893
|
-
}), e.prototype.$init = function() {
|
|
894
|
-
return this.popup = new i(this.parentNode || document.body || document.documentElement), this.popup.on("click", function(e) {
|
|
895
|
-
this.insertMatch(), e.stop();
|
|
896
|
-
}.bind(this)), this.popup.focus = this.editor.focus.bind(this.editor), this.popup.on("show", this.$onPopupShow.bind(this)), this.popup.on("hide", this.$onHidePopup.bind(this)), this.popup.on("select", this.$onPopupChange.bind(this)), f.addListener(this.popup.container, "mouseout", this.mouseOutListener.bind(this)), this.popup.on("changeHoverMarker", this.tooltipTimer.bind(null, null)), this.popup.renderer.on("afterRender", this.$onPopupRender.bind(this)), this.popup;
|
|
897
|
-
}, e.prototype.$initInline = function() {
|
|
898
|
-
if (this.inlineEnabled && !this.inlineRenderer) return this.inlineRenderer = new a(), this.inlineRenderer;
|
|
899
|
-
}, e.prototype.getPopup = function() {
|
|
900
|
-
return this.popup || this.$init();
|
|
901
|
-
}, e.prototype.$onHidePopup = function() {
|
|
902
|
-
this.inlineRenderer && this.inlineRenderer.hide(), this.hideDocTooltip(), this.stickySelectionTimer.cancel(), this.popupTimer.cancel(), this.stickySelection = !1;
|
|
903
|
-
}, e.prototype.$seen = function(e) {
|
|
904
|
-
!this.hasSeen.has(e) && e && e.completer && e.completer.onSeen && typeof e.completer.onSeen == "function" && (e.completer.onSeen(this.editor, e), this.hasSeen.add(e));
|
|
905
|
-
}, e.prototype.$onPopupChange = function(e) {
|
|
906
|
-
if (this.inlineRenderer && this.inlineEnabled) {
|
|
907
|
-
var t = e ? null : this.popup.getData(this.popup.getRow());
|
|
908
|
-
if (this.$updateGhostText(t), this.popup.isMouseOver && this.setSelectOnHover) {
|
|
909
|
-
this.tooltipTimer.call(null, null);
|
|
910
|
-
return;
|
|
911
|
-
}
|
|
912
|
-
this.popupTimer.schedule(), this.tooltipTimer.schedule();
|
|
913
|
-
} else this.popupTimer.call(null, null), this.tooltipTimer.call(null, null);
|
|
914
|
-
}, e.prototype.$updateGhostText = function(e) {
|
|
915
|
-
var t = this.base.row, n = this.base.column, r = this.editor.getCursorPosition().column, i = this.editor.session.getLine(t).slice(n, r);
|
|
916
|
-
this.inlineRenderer.show(this.editor, e, i) ? this.$seen(e) : this.inlineRenderer.hide();
|
|
917
|
-
}, e.prototype.$onPopupRender = function() {
|
|
918
|
-
var e = this.inlineRenderer && this.inlineEnabled;
|
|
919
|
-
if (this.completions && this.completions.filtered && this.completions.filtered.length > 0) for (var t = this.popup.getFirstVisibleRow(); t <= this.popup.getLastVisibleRow(); t++) {
|
|
920
|
-
var n = this.popup.getData(t);
|
|
921
|
-
n && (!e || n.hideInlinePreview) && this.$seen(n);
|
|
922
|
-
}
|
|
923
|
-
}, e.prototype.$onPopupShow = function(e) {
|
|
924
|
-
this.$onPopupChange(e), this.stickySelection = !1, this.stickySelectionDelay >= 0 && this.stickySelectionTimer.schedule(this.stickySelectionDelay);
|
|
925
|
-
}, e.prototype.observeLayoutChanges = function() {
|
|
926
|
-
if (!this.$elements && this.editor) {
|
|
927
|
-
window.addEventListener("resize", this.onLayoutChange, { passive: !0 }), window.addEventListener("wheel", this.mousewheelListener);
|
|
928
|
-
for (var e = this.editor.container.parentNode, t = []; e;) t.push(e), e.addEventListener("scroll", this.onLayoutChange, { passive: !0 }), e = e.parentNode;
|
|
929
|
-
this.$elements = t;
|
|
930
|
-
}
|
|
931
|
-
}, e.prototype.unObserveLayoutChanges = function() {
|
|
932
|
-
var e = this;
|
|
933
|
-
window.removeEventListener("resize", this.onLayoutChange, { passive: !0 }), window.removeEventListener("wheel", this.mousewheelListener), this.$elements && this.$elements.forEach(function(t) {
|
|
934
|
-
t.removeEventListener("scroll", e.onLayoutChange, { passive: !0 });
|
|
935
|
-
}), this.$elements = null;
|
|
936
|
-
}, e.prototype.onLayoutChange = function() {
|
|
937
|
-
if (!this.popup.isOpen) return this.unObserveLayoutChanges();
|
|
938
|
-
this.$updatePopupPosition(), this.updateDocTooltip();
|
|
939
|
-
}, e.prototype.$updatePopupPosition = function() {
|
|
940
|
-
var e = this.editor, t = e.renderer, n = t.layerConfig.lineHeight, r = t.$cursorLayer.getPixelPosition(this.base, !0);
|
|
941
|
-
r.left -= this.popup.getTextLeftOffset();
|
|
942
|
-
var i = e.container.getBoundingClientRect();
|
|
943
|
-
r.top += i.top - t.layerConfig.offset, r.left += i.left - e.renderer.scrollLeft, r.left += t.gutterWidth;
|
|
944
|
-
var a = {
|
|
945
|
-
top: r.top,
|
|
946
|
-
left: r.left
|
|
947
|
-
};
|
|
948
|
-
t.$ghostText && t.$ghostTextWidget && this.base.row === t.$ghostText.position.row && (a.top += t.$ghostTextWidget.el.offsetHeight);
|
|
949
|
-
var o = e.container.getBoundingClientRect().bottom - n, s = o < a.top ? {
|
|
950
|
-
top: o,
|
|
951
|
-
left: a.left
|
|
952
|
-
} : a;
|
|
953
|
-
this.popup.tryShow(s, n, "bottom") || this.popup.tryShow(r, n, "top") || this.popup.show(r, n);
|
|
954
|
-
}, e.prototype.openPopup = function(e, t, n) {
|
|
955
|
-
this.$firstOpenTimer.cancel(), this.popup || this.$init(), this.inlineEnabled && !this.inlineRenderer && this.$initInline(), this.popup.autoSelect = this.autoSelect, this.popup.setSelectOnHover(this.setSelectOnHover);
|
|
956
|
-
var r = this.popup.getRow(), i = this.popup.data[r];
|
|
957
|
-
this.popup.setData(this.completions.filtered, this.completions.filterText), this.editor.textInput.setAriaOptions && this.editor.textInput.setAriaOptions({
|
|
958
|
-
activeDescendant: o(this.popup.getRow()),
|
|
959
|
-
inline: this.inlineEnabled
|
|
960
|
-
}), e.keyBinding.addKeyboardHandler(this.keyboardHandler);
|
|
961
|
-
var a;
|
|
962
|
-
this.stickySelection && (a = this.popup.data.indexOf(i)), (!a || a === -1) && (a = 0), this.popup.setRow(this.autoSelect ? a : -1), a === r && i !== this.completions.filtered[a] && this.$onPopupChange();
|
|
963
|
-
var s = this.inlineRenderer && this.inlineEnabled;
|
|
964
|
-
if (a === r && s) {
|
|
965
|
-
var c = this.popup.getData(this.popup.getRow());
|
|
966
|
-
this.$updateGhostText(c);
|
|
967
|
-
}
|
|
968
|
-
n || (this.popup.setTheme(e.getTheme()), this.popup.setFontSize(e.getFontSize()), this.$updatePopupPosition(), this.tooltipNode && this.updateDocTooltip()), this.changeTimer.cancel(), this.observeLayoutChanges();
|
|
969
|
-
}, e.prototype.detach = function() {
|
|
970
|
-
this.editor && (this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler), this.editor.off("changeSelection", this.changeListener), this.editor.off("blur", this.blurListener), this.editor.off("mousedown", this.mousedownListener), this.editor.off("mousewheel", this.mousewheelListener)), this.$firstOpenTimer.cancel(), this.changeTimer.cancel(), this.hideDocTooltip(), this.completionProvider && this.completionProvider.detach(), this.popup && this.popup.isOpen && this.popup.hide(), this.popup && this.popup.renderer && this.popup.renderer.off("afterRender", this.$onPopupRender), this.base && this.base.detach(), this.activated = !1, this.completionProvider = this.completions = this.base = null, this.unObserveLayoutChanges();
|
|
971
|
-
}, e.prototype.changeListener = function(e) {
|
|
972
|
-
var t = this.editor.selection.lead;
|
|
973
|
-
(t.row != this.base.row || t.column < this.base.column) && this.detach(), this.activated ? this.changeTimer.schedule() : this.detach();
|
|
974
|
-
}, e.prototype.blurListener = function(e) {
|
|
975
|
-
var t = document.activeElement, n = this.editor.textInput.getElement(), r = e.relatedTarget && this.tooltipNode && this.tooltipNode.contains(e.relatedTarget), i = this.popup && this.popup.container;
|
|
976
|
-
t != n && t.parentNode != i && !r && t != this.tooltipNode && e.relatedTarget != n && this.detach();
|
|
977
|
-
}, e.prototype.mousedownListener = function(e) {
|
|
978
|
-
this.detach();
|
|
979
|
-
}, e.prototype.mousewheelListener = function(e) {
|
|
980
|
-
this.popup && !this.popup.isMouseOver && this.detach();
|
|
981
|
-
}, e.prototype.mouseOutListener = function(e) {
|
|
982
|
-
this.popup.isOpen && this.$updatePopupPosition();
|
|
983
|
-
}, e.prototype.goTo = function(e) {
|
|
984
|
-
this.popup.goTo(e);
|
|
985
|
-
}, e.prototype.insertMatch = function(e, t) {
|
|
986
|
-
if (e ||= this.popup.getData(this.popup.getRow()), !e) return !1;
|
|
987
|
-
if (e.value === "") return this.detach();
|
|
988
|
-
var n = this.completions, r = this.getCompletionProvider().insertMatch(this.editor, e, n.filterText, t);
|
|
989
|
-
return this.completions == n && this.detach(), r;
|
|
990
|
-
}, e.prototype.showPopup = function(e, t) {
|
|
991
|
-
this.editor && this.detach(), this.activated = !0, this.editor = e, e.completer != this && (e.completer && e.completer.detach(), e.completer = this), e.on("changeSelection", this.changeListener), e.on("blur", this.blurListener), e.on("mousedown", this.mousedownListener), e.on("mousewheel", this.mousewheelListener), this.updateCompletions(!1, t);
|
|
992
|
-
}, e.prototype.getCompletionProvider = function(e) {
|
|
993
|
-
return this.completionProvider ||= new g(e), this.completionProvider;
|
|
994
|
-
}, e.prototype.gatherCompletions = function(e, t) {
|
|
995
|
-
return this.getCompletionProvider().gatherCompletions(e, t);
|
|
996
|
-
}, e.prototype.updateCompletions = function(t, n) {
|
|
997
|
-
if (t && this.base && this.completions) {
|
|
998
|
-
var r = this.editor.getCursorPosition(), i = this.editor.session.getTextRange({
|
|
999
|
-
start: this.base,
|
|
1000
|
-
end: r
|
|
1001
|
-
});
|
|
1002
|
-
if (i == this.completions.filterText) return;
|
|
1003
|
-
if (this.completions.setFilter(i), !this.completions.filtered.length || this.completions.filtered.length == 1 && this.completions.filtered[0].value == i && !this.completions.filtered[0].snippet) return this.detach();
|
|
1004
|
-
this.openPopup(this.editor, i, t);
|
|
1005
|
-
return;
|
|
1006
|
-
}
|
|
1007
|
-
if (n && n.matches) {
|
|
1008
|
-
var r = this.editor.getSelectionRange().start;
|
|
1009
|
-
return this.base = this.editor.session.doc.createAnchor(r.row, r.column), this.base.$insertRight = !0, this.completions = new _(n.matches), this.getCompletionProvider().completions = this.completions, this.openPopup(this.editor, "", t);
|
|
1010
|
-
}
|
|
1011
|
-
var a = this.editor.getSession(), r = this.editor.getCursorPosition(), i = s.getCompletionPrefix(this.editor);
|
|
1012
|
-
this.base = a.doc.createAnchor(r.row, r.column - i.length), this.base.$insertRight = !0;
|
|
1013
|
-
var o = {
|
|
1014
|
-
exactMatch: this.exactMatch,
|
|
1015
|
-
ignoreCaption: this.ignoreCaption
|
|
1016
|
-
};
|
|
1017
|
-
this.getCompletionProvider({
|
|
1018
|
-
prefix: i,
|
|
1019
|
-
pos: r
|
|
1020
|
-
}).provideCompletions(this.editor, o, function(n, r, i) {
|
|
1021
|
-
var a = r.filtered, o = s.getCompletionPrefix(this.editor);
|
|
1022
|
-
if (this.$firstOpenTimer.cancel(), i) {
|
|
1023
|
-
if (!a.length) {
|
|
1024
|
-
var c = !this.autoShown && this.emptyMessage;
|
|
1025
|
-
if (typeof c == "function" && (c = this.emptyMessage(o)), c) {
|
|
1026
|
-
var l = [{
|
|
1027
|
-
caption: c,
|
|
1028
|
-
value: ""
|
|
1029
|
-
}];
|
|
1030
|
-
this.completions = new _(l), this.openPopup(this.editor, o, t), this.popup.renderer.setStyle("ace_loading", !1), this.popup.renderer.setStyle("ace_empty-message", !0);
|
|
1031
|
-
return;
|
|
1032
|
-
}
|
|
1033
|
-
return this.detach();
|
|
1034
|
-
}
|
|
1035
|
-
if (a.length == 1 && a[0].value == o && !a[0].snippet) return this.detach();
|
|
1036
|
-
if (this.autoInsert && !this.autoShown && a.length == 1) return this.insertMatch(a[0]);
|
|
1037
|
-
}
|
|
1038
|
-
this.completions = !i && this.showLoadingState ? new _(e.completionsForLoading.concat(a), r.filterText) : r, this.openPopup(this.editor, o, t), this.popup.renderer.setStyle("ace_empty-message", !1), this.popup.renderer.setStyle("ace_loading", !i);
|
|
1039
|
-
}.bind(this)), this.showLoadingState && !this.autoShown && !(this.popup && this.popup.isOpen) && this.$firstOpenTimer.delay(this.stickySelectionDelay / 2);
|
|
1040
|
-
}, e.prototype.cancelContextMenu = function() {
|
|
1041
|
-
this.editor.$mouseHandler.cancelContextMenu();
|
|
1042
|
-
}, e.prototype.updateDocTooltip = function() {
|
|
1043
|
-
var e = this.popup, t = this.completions && this.completions.filtered, n = t && (t[e.getHoveredRow()] || t[e.getRow()]), r = null;
|
|
1044
|
-
if (!n || !this.editor || !this.popup.isOpen) return this.hideDocTooltip();
|
|
1045
|
-
for (var i = this.editor.completers.length, a = 0; a < i; a++) {
|
|
1046
|
-
var o = this.editor.completers[a];
|
|
1047
|
-
if (o.getDocTooltip && n.completerId === o.id) {
|
|
1048
|
-
r = o.getDocTooltip(n);
|
|
1049
|
-
break;
|
|
1050
|
-
}
|
|
1051
|
-
}
|
|
1052
|
-
if (!r && typeof n != "string" && (r = n), typeof r == "string" && (r = { docText: r }), !r || !(r.docHTML || r.docText)) return this.hideDocTooltip();
|
|
1053
|
-
this.showDocTooltip(r);
|
|
1054
|
-
}, e.prototype.showDocTooltip = function(e) {
|
|
1055
|
-
this.tooltipNode || (this.tooltipNode = l.createElement("div"), this.tooltipNode.style.margin = "0", this.tooltipNode.style.pointerEvents = "auto", this.tooltipNode.style.overscrollBehavior = "contain", this.tooltipNode.tabIndex = -1, this.tooltipNode.onblur = this.blurListener.bind(this), this.tooltipNode.onclick = this.onTooltipClick.bind(this), this.tooltipNode.id = "doc-tooltip", this.tooltipNode.setAttribute("role", "tooltip"), this.tooltipNode.addEventListener("wheel", p));
|
|
1056
|
-
var t = this.editor.renderer.theme;
|
|
1057
|
-
this.tooltipNode.className = "ace_tooltip ace_doc-tooltip " + (t.isDark ? "ace_dark " : "") + (t.cssClass || "");
|
|
1058
|
-
var n = this.tooltipNode;
|
|
1059
|
-
e.docHTML ? n.innerHTML = e.docHTML : e.docText && (n.textContent = e.docText), n.parentNode || this.popup.container.appendChild(this.tooltipNode);
|
|
1060
|
-
var r = this.popup, i = r.container.getBoundingClientRect(), a = 400, o = 300, s = r.renderer.scrollBar.width || 10, c = i.left, u = window.innerWidth - i.right - s, d = r.isTopdown ? window.innerHeight - s - i.bottom : i.top, f = [
|
|
1061
|
-
Math.min(u / a, 1),
|
|
1062
|
-
Math.min(c / a, 1),
|
|
1063
|
-
Math.min(d / o, 1) * .9
|
|
1064
|
-
], m = Math.max.apply(Math, f), h = n.style;
|
|
1065
|
-
h.display = "block", m == f[0] || f[0] >= 1 ? (h.left = i.right + 1 + "px", h.right = "", h.maxWidth = a * m + "px", h.top = i.top + "px", h.bottom = "", h.maxHeight = Math.min(window.innerHeight - s - i.top, o) + "px") : m == f[1] || f[1] >= 1 ? (h.right = window.innerWidth - i.left + "px", h.left = "", h.maxWidth = a * m + "px", h.top = i.top + "px", h.bottom = "", h.maxHeight = Math.min(window.innerHeight - s - i.top, o) + "px") : m == f[2] && (h.left = i.left + "px", h.right = "", h.maxWidth = Math.min(a, window.innerWidth - i.left) + "px", r.isTopdown ? (h.top = i.bottom + "px", h.bottom = "", h.maxHeight = Math.min(window.innerHeight - s - i.bottom, o) + "px") : (h.top = "", h.bottom = window.innerHeight - i.top + "px", h.maxHeight = Math.min(i.top, o) + "px")), l.$fixPositionBug(n);
|
|
1066
|
-
}, e.prototype.hideDocTooltip = function() {
|
|
1067
|
-
if (this.tooltipTimer.cancel(), this.tooltipNode) {
|
|
1068
|
-
var e = this.tooltipNode;
|
|
1069
|
-
!this.editor.isFocused() && document.activeElement == e && this.editor.focus(), this.tooltipNode = null, e.parentNode && e.parentNode.removeChild(e);
|
|
1070
|
-
}
|
|
1071
|
-
}, e.prototype.onTooltipClick = function(e) {
|
|
1072
|
-
for (var t = e.target; t && t != this.tooltipNode;) {
|
|
1073
|
-
if (t.nodeName == "A" && t.href) {
|
|
1074
|
-
t.rel = "noreferrer", t.target = "_blank";
|
|
1075
|
-
break;
|
|
1076
|
-
}
|
|
1077
|
-
t = t.parentNode;
|
|
1078
|
-
}
|
|
1079
|
-
}, e.prototype.destroy = function() {
|
|
1080
|
-
if (this.detach(), this.popup) {
|
|
1081
|
-
this.popup.destroy();
|
|
1082
|
-
var e = this.popup.container;
|
|
1083
|
-
e && e.parentNode && e.parentNode.removeChild(e);
|
|
1084
|
-
}
|
|
1085
|
-
this.editor && this.editor.completer == this && (this.editor.off("destroy", m), this.editor.completer = null), this.inlineRenderer = this.popup = this.editor = null;
|
|
1086
|
-
}, e.for = function(t) {
|
|
1087
|
-
return t.completer instanceof e ? t.completer : (t.completer &&= (t.completer.destroy(), null), d.get("sharedPopups") ? (e.$sharedInstance ||= new e(), t.completer = e.$sharedInstance) : (t.completer = new e(), t.once("destroy", m)), t.completer);
|
|
1088
|
-
}, e;
|
|
1089
|
-
}();
|
|
1090
|
-
h.prototype.commands = {
|
|
1091
|
-
Up: function(e) {
|
|
1092
|
-
e.completer.goTo("up");
|
|
1093
|
-
},
|
|
1094
|
-
Down: function(e) {
|
|
1095
|
-
e.completer.goTo("down");
|
|
1096
|
-
},
|
|
1097
|
-
"Ctrl-Up|Ctrl-Home": function(e) {
|
|
1098
|
-
e.completer.goTo("start");
|
|
1099
|
-
},
|
|
1100
|
-
"Ctrl-Down|Ctrl-End": function(e) {
|
|
1101
|
-
e.completer.goTo("end");
|
|
1102
|
-
},
|
|
1103
|
-
Esc: function(e) {
|
|
1104
|
-
e.completer.detach();
|
|
1105
|
-
},
|
|
1106
|
-
Return: function(e) {
|
|
1107
|
-
return e.completer.insertMatch();
|
|
1108
|
-
},
|
|
1109
|
-
"Shift-Return": function(e) {
|
|
1110
|
-
e.completer.insertMatch(null, { deleteSuffix: !0 });
|
|
1111
|
-
},
|
|
1112
|
-
Tab: function(e) {
|
|
1113
|
-
var t = e.completer.insertMatch();
|
|
1114
|
-
if (!t && !e.tabstopManager) e.completer.goTo("down");
|
|
1115
|
-
else return t;
|
|
1116
|
-
},
|
|
1117
|
-
Backspace: function(e) {
|
|
1118
|
-
e.execCommand("backspace"), !s.getCompletionPrefix(e) && e.completer && e.completer.detach();
|
|
1119
|
-
},
|
|
1120
|
-
PageUp: function(e) {
|
|
1121
|
-
e.completer.popup.gotoPageUp();
|
|
1122
|
-
},
|
|
1123
|
-
PageDown: function(e) {
|
|
1124
|
-
e.completer.popup.gotoPageDown();
|
|
1125
|
-
}
|
|
1126
|
-
}, h.startCommand = {
|
|
1127
|
-
name: "startAutocomplete",
|
|
1128
|
-
exec: function(e, t) {
|
|
1129
|
-
var n = h.for(e);
|
|
1130
|
-
n.autoInsert = !1, n.autoSelect = !0, n.autoShown = !1, n.showPopup(e, t), n.cancelContextMenu();
|
|
1131
|
-
},
|
|
1132
|
-
bindKey: "Ctrl-Space|Ctrl-Shift-Space|Alt-Space"
|
|
1133
|
-
};
|
|
1134
|
-
var g = function() {
|
|
1135
|
-
function e(e) {
|
|
1136
|
-
this.initialPosition = e, this.active = !0;
|
|
1137
|
-
}
|
|
1138
|
-
return e.prototype.insertByIndex = function(e, t, n) {
|
|
1139
|
-
return !this.completions || !this.completions.filtered ? !1 : this.insertMatch(e, this.completions.filtered[t], n);
|
|
1140
|
-
}, e.prototype.insertMatch = function(e, t, n) {
|
|
1141
|
-
if (!t) return !1;
|
|
1142
|
-
if (e.startOperation({ command: { name: "insertMatch" } }), t.completer && t.completer.insertMatch) t.completer.insertMatch(e, t);
|
|
1143
|
-
else {
|
|
1144
|
-
if (!this.completions) return !1;
|
|
1145
|
-
var r = this.completions.filterText.length, i = 0;
|
|
1146
|
-
if (t.range && t.range.start.row === t.range.end.row && (r -= this.initialPosition.prefix.length, r += this.initialPosition.pos.column - t.range.start.column, i += t.range.end.column - this.initialPosition.pos.column), r || i) for (var a = e.selection.getAllRanges ? e.selection.getAllRanges() : [e.getSelectionRange()], o = 0, s; s = a[o]; o++) s.start.column -= r, s.end.column += i, e.session.remove(s);
|
|
1147
|
-
t.snippet ? u.insertSnippet(e, t.snippet) : this.$insertString(e, t), t.completer && t.completer.onInsert && typeof t.completer.onInsert == "function" && t.completer.onInsert(e, t), t.command && t.command === "startAutocomplete" && e.execCommand(t.command);
|
|
1148
|
-
}
|
|
1149
|
-
return e.endOperation(), !0;
|
|
1150
|
-
}, e.prototype.$insertString = function(e, t) {
|
|
1151
|
-
var n = t.value || t;
|
|
1152
|
-
e.execCommand("insertstring", n);
|
|
1153
|
-
}, e.prototype.gatherCompletions = function(e, t) {
|
|
1154
|
-
var n = e.getSession(), r = e.getCursorPosition(), i = s.getCompletionPrefix(e), a = [];
|
|
1155
|
-
this.completers = e.completers;
|
|
1156
|
-
var o = e.completers.length;
|
|
1157
|
-
return e.completers.forEach(function(c, l) {
|
|
1158
|
-
c.getCompletions(e, n, r, i, function(n, r) {
|
|
1159
|
-
c.hideInlinePreview && (r = r.map(function(e) {
|
|
1160
|
-
return Object.assign(e, { hideInlinePreview: c.hideInlinePreview });
|
|
1161
|
-
})), !n && r && (a = a.concat(r)), t(null, {
|
|
1162
|
-
prefix: s.getCompletionPrefix(e),
|
|
1163
|
-
matches: a,
|
|
1164
|
-
finished: --o === 0
|
|
1165
|
-
});
|
|
1166
|
-
});
|
|
1167
|
-
}), !0;
|
|
1168
|
-
}, e.prototype.provideCompletions = function(e, t, n) {
|
|
1169
|
-
var r = function(e) {
|
|
1170
|
-
var r = e.prefix, i = e.matches;
|
|
1171
|
-
this.completions = new _(i), t.exactMatch && (this.completions.exactMatch = !0), t.ignoreCaption && (this.completions.ignoreCaption = !0), this.completions.setFilter(r), (e.finished || this.completions.filtered.length) && n(null, this.completions, e.finished);
|
|
1172
|
-
}.bind(this), i = !0, a = null;
|
|
1173
|
-
if (this.gatherCompletions(e, function(e, t) {
|
|
1174
|
-
if (this.active && (e && (n(e, [], !0), this.detach()), t.prefix.indexOf(t.prefix) === 0)) {
|
|
1175
|
-
if (i) {
|
|
1176
|
-
a = t;
|
|
1177
|
-
return;
|
|
1178
|
-
}
|
|
1179
|
-
r(t);
|
|
1180
|
-
}
|
|
1181
|
-
}.bind(this)), i = !1, a) {
|
|
1182
|
-
var o = a;
|
|
1183
|
-
a = null, r(o);
|
|
1184
|
-
}
|
|
1185
|
-
}, e.prototype.detach = function() {
|
|
1186
|
-
this.active = !1, this.completers && this.completers.forEach(function(e) {
|
|
1187
|
-
typeof e.cancel == "function" && e.cancel();
|
|
1188
|
-
});
|
|
1189
|
-
}, e;
|
|
1190
|
-
}(), _ = function() {
|
|
1191
|
-
function e(e, t) {
|
|
1192
|
-
this.all = e, this.filtered = e, this.filterText = t || "", this.exactMatch = !1, this.ignoreCaption = !1;
|
|
1193
|
-
}
|
|
1194
|
-
return e.prototype.setFilter = function(e) {
|
|
1195
|
-
if (e.length > this.filterText && e.lastIndexOf(this.filterText, 0) === 0) var t = this.filtered;
|
|
1196
|
-
else var t = this.all;
|
|
1197
|
-
this.filterText = e, t = this.filterCompletions(t, this.filterText), t = t.sort(function(e, t) {
|
|
1198
|
-
return t.exactMatch - e.exactMatch || t.$score - e.$score || (e.caption || e.value).localeCompare(t.caption || t.value);
|
|
1199
|
-
});
|
|
1200
|
-
var n = null;
|
|
1201
|
-
t = t.filter(function(e) {
|
|
1202
|
-
var t = e.snippet || e.caption || e.value;
|
|
1203
|
-
return t !== n && (n = t, !0);
|
|
1204
|
-
}), this.filtered = t;
|
|
1205
|
-
}, e.prototype.filterCompletions = function(e, t) {
|
|
1206
|
-
var n = [], r = t.toUpperCase(), i = t.toLowerCase();
|
|
1207
|
-
loop: for (var a = 0, o; o = e[a]; a++) {
|
|
1208
|
-
if (o.skipFilter) {
|
|
1209
|
-
o.$score = o.score, n.push(o);
|
|
1210
|
-
continue;
|
|
1211
|
-
}
|
|
1212
|
-
var s = !this.ignoreCaption && o.caption || o.value || o.snippet;
|
|
1213
|
-
if (s) {
|
|
1214
|
-
var c = -1, l = 0, u = 0, d, f;
|
|
1215
|
-
if (this.exactMatch) {
|
|
1216
|
-
if (t !== s.substr(0, t.length)) continue loop;
|
|
1217
|
-
} else {
|
|
1218
|
-
var p = s.toLowerCase().indexOf(i);
|
|
1219
|
-
if (p > -1) u = p;
|
|
1220
|
-
else for (var m = 0; m < t.length; m++) {
|
|
1221
|
-
var h = s.indexOf(i[m], c + 1), g = s.indexOf(r[m], c + 1);
|
|
1222
|
-
if (d = h >= 0 && (g < 0 || h < g) ? h : g, d < 0) continue loop;
|
|
1223
|
-
f = d - c - 1, f > 0 && (c === -1 && (u += 10), u += f, l |= 1 << m), c = d;
|
|
1224
|
-
}
|
|
1225
|
-
}
|
|
1226
|
-
o.matchMask = l, o.exactMatch = +!u, o.$score = (o.score || 0) - u, n.push(o);
|
|
1227
|
-
}
|
|
1228
|
-
}
|
|
1229
|
-
return n;
|
|
1230
|
-
}, e;
|
|
1231
|
-
}();
|
|
1232
|
-
t.Autocomplete = h, t.CompletionProvider = g, t.FilteredList = _;
|
|
1233
|
-
}), ace.define("ace/marker_group", [
|
|
1234
|
-
"require",
|
|
1235
|
-
"exports",
|
|
1236
|
-
"module"
|
|
1237
|
-
], function(e, t, n) {
|
|
1238
|
-
var r = function() {
|
|
1239
|
-
function e(e, t) {
|
|
1240
|
-
t && (this.markerType = t.markerType), this.markers = [], this.session = e, e.addDynamicMarker(this);
|
|
1241
|
-
}
|
|
1242
|
-
return e.prototype.getMarkerAtPosition = function(e) {
|
|
1243
|
-
return this.markers.find(function(t) {
|
|
1244
|
-
return t.range.contains(e.row, e.column);
|
|
1245
|
-
});
|
|
1246
|
-
}, e.prototype.markersComparator = function(e, t) {
|
|
1247
|
-
return e.range.start.row - t.range.start.row;
|
|
1248
|
-
}, e.prototype.setMarkers = function(e) {
|
|
1249
|
-
this.markers = e.sort(this.markersComparator).slice(0, this.MAX_MARKERS), this.session._signal("changeBackMarker");
|
|
1250
|
-
}, e.prototype.update = function(e, t, n, r) {
|
|
1251
|
-
if (this.markers && this.markers.length) for (var i = r.firstRow, a = r.lastRow, o, s = 0, c = 0, l = 0; l < this.markers.length; l++) {
|
|
1252
|
-
var u = this.markers[l];
|
|
1253
|
-
if (!(u.range.end.row < i) && !(u.range.start.row > a) && (u.range.start.row === c ? s++ : (c = u.range.start.row, s = 0), !(s > 200))) {
|
|
1254
|
-
var d = u.range.clipRows(i, a);
|
|
1255
|
-
if (d.start.row !== d.end.row || d.start.column !== d.end.column) {
|
|
1256
|
-
var f = d.toScreenRange(n);
|
|
1257
|
-
if (f.isEmpty()) {
|
|
1258
|
-
o = n.getNextFoldLine(d.end.row, o), o && o.end.row > d.end.row && (i = o.end.row);
|
|
1259
|
-
continue;
|
|
1260
|
-
}
|
|
1261
|
-
this.markerType === "fullLine" ? t.drawFullLineMarker(e, f, u.className, r) : f.isMultiLine() ? this.markerType === "line" ? t.drawMultiLineMarker(e, f, u.className, r) : t.drawTextMarker(e, f, u.className, r) : t.drawSingleLineMarker(e, f, u.className + " ace_br15", r);
|
|
1262
|
-
}
|
|
1263
|
-
}
|
|
1264
|
-
}
|
|
1265
|
-
}, e;
|
|
1266
|
-
}();
|
|
1267
|
-
r.prototype.MAX_MARKERS = 1e4, t.MarkerGroup = r;
|
|
1268
|
-
}), ace.define("ace/autocomplete/text_completer", [
|
|
1269
|
-
"require",
|
|
1270
|
-
"exports",
|
|
1271
|
-
"module",
|
|
1272
|
-
"ace/range"
|
|
1273
|
-
], function(e, t, n) {
|
|
1274
|
-
var r = e("../range").Range, i = /[^a-zA-Z_0-9\$\-\u00C0-\u1FFF\u2C00-\uD7FF\w]+/;
|
|
1275
|
-
function a(e, t) {
|
|
1276
|
-
return e.getTextRange(r.fromPoints({
|
|
1277
|
-
row: 0,
|
|
1278
|
-
column: 0
|
|
1279
|
-
}, t)).split(i).length - 1;
|
|
1280
|
-
}
|
|
1281
|
-
function o(e, t) {
|
|
1282
|
-
var n = a(e, t), r = e.getValue().split(i), o = Object.create(null), s = r[n];
|
|
1283
|
-
return r.forEach(function(e, t) {
|
|
1284
|
-
if (e && e !== s) {
|
|
1285
|
-
var i = Math.abs(n - t), a = r.length - i;
|
|
1286
|
-
o[e] = o[e] ? Math.max(a, o[e]) : a;
|
|
1287
|
-
}
|
|
1288
|
-
}), o;
|
|
1289
|
-
}
|
|
1290
|
-
t.id = "textCompleter", t.getCompletions = function(e, t, n, r, i) {
|
|
1291
|
-
var a = o(t, n);
|
|
1292
|
-
i(null, Object.keys(a).map(function(e) {
|
|
1293
|
-
return {
|
|
1294
|
-
caption: e,
|
|
1295
|
-
value: e,
|
|
1296
|
-
score: a[e],
|
|
1297
|
-
meta: "local"
|
|
1298
|
-
};
|
|
1299
|
-
}));
|
|
1300
|
-
};
|
|
1301
|
-
}), ace.define("ace/ext/language_tools", [
|
|
1302
|
-
"require",
|
|
1303
|
-
"exports",
|
|
1304
|
-
"module",
|
|
1305
|
-
"ace/snippets",
|
|
1306
|
-
"ace/autocomplete",
|
|
1307
|
-
"ace/config",
|
|
1308
|
-
"ace/lib/lang",
|
|
1309
|
-
"ace/autocomplete/util",
|
|
1310
|
-
"ace/marker_group",
|
|
1311
|
-
"ace/autocomplete/text_completer",
|
|
1312
|
-
"ace/editor",
|
|
1313
|
-
"ace/config"
|
|
1314
|
-
], function(e, t, n) {
|
|
1315
|
-
var r = e("../snippets").snippetManager, i = e("../autocomplete").Autocomplete, a = e("../config"), o = e("../lib/lang"), s = e("../autocomplete/util"), c = e("../marker_group").MarkerGroup, l = e("../autocomplete/text_completer"), u = {
|
|
1316
|
-
getCompletions: function(e, t, n, r, i) {
|
|
1317
|
-
if (t.$mode.completer) return t.$mode.completer.getCompletions(e, t, n, r, i);
|
|
1318
|
-
var a = e.session.getState(n.row), o = t.$mode.getCompletions(a, t, n, r);
|
|
1319
|
-
o = o.map(function(e) {
|
|
1320
|
-
return e.completerId = u.id, e;
|
|
1321
|
-
}), i(null, o);
|
|
1322
|
-
},
|
|
1323
|
-
id: "keywordCompleter"
|
|
1324
|
-
}, d = function(e) {
|
|
1325
|
-
var t = {};
|
|
1326
|
-
return e.replace(/\${(\d+)(:(.*?))?}/g, function(e, n, r, i) {
|
|
1327
|
-
return t[n] = i || "";
|
|
1328
|
-
}).replace(/\$(\d+?)/g, function(e, n) {
|
|
1329
|
-
return t[n];
|
|
1330
|
-
});
|
|
1331
|
-
}, f = {
|
|
1332
|
-
getCompletions: function(e, t, n, i, a) {
|
|
1333
|
-
var o = [], s = t.getTokenAt(n.row, n.column);
|
|
1334
|
-
s && s.type.match(/(tag-name|tag-open|tag-whitespace|attribute-name|attribute-value)\.xml$/) ? o.push("html-tag") : o = r.getActiveScopes(e);
|
|
1335
|
-
var c = r.snippetMap, l = [];
|
|
1336
|
-
o.forEach(function(e) {
|
|
1337
|
-
for (var t = c[e] || [], n = t.length; n--;) {
|
|
1338
|
-
var r = t[n], i = r.name || r.tabTrigger;
|
|
1339
|
-
i && l.push({
|
|
1340
|
-
caption: i,
|
|
1341
|
-
snippet: r.content,
|
|
1342
|
-
meta: r.tabTrigger && !r.name ? r.tabTrigger + "⇥ " : "snippet",
|
|
1343
|
-
completerId: f.id
|
|
1344
|
-
});
|
|
1345
|
-
}
|
|
1346
|
-
}, this), a(null, l);
|
|
1347
|
-
},
|
|
1348
|
-
getDocTooltip: function(e) {
|
|
1349
|
-
e.snippet && !e.docHTML && (e.docHTML = [
|
|
1350
|
-
"<b>",
|
|
1351
|
-
o.escapeHTML(e.caption),
|
|
1352
|
-
"</b>",
|
|
1353
|
-
"<hr></hr>",
|
|
1354
|
-
o.escapeHTML(d(e.snippet))
|
|
1355
|
-
].join(""));
|
|
1356
|
-
},
|
|
1357
|
-
id: "snippetCompleter"
|
|
1358
|
-
}, p = [
|
|
1359
|
-
f,
|
|
1360
|
-
l,
|
|
1361
|
-
u
|
|
1362
|
-
];
|
|
1363
|
-
t.setCompleters = function(e) {
|
|
1364
|
-
p.length = 0, e && p.push.apply(p, e);
|
|
1365
|
-
}, t.addCompleter = function(e) {
|
|
1366
|
-
p.push(e);
|
|
1367
|
-
}, t.textCompleter = l, t.keyWordCompleter = u, t.snippetCompleter = f;
|
|
1368
|
-
var m = {
|
|
1369
|
-
name: "expandSnippet",
|
|
1370
|
-
exec: function(e) {
|
|
1371
|
-
return r.expandWithTab(e);
|
|
1372
|
-
},
|
|
1373
|
-
bindKey: "Tab"
|
|
1374
|
-
}, h = function(e, t) {
|
|
1375
|
-
g(t.session.$mode);
|
|
1376
|
-
}, g = function(e) {
|
|
1377
|
-
typeof e == "string" && (e = a.$modes[e]), e && (r.files ||= {}, _(e.$id, e.snippetFileId), e.modes && e.modes.forEach(g));
|
|
1378
|
-
}, _ = function(e, t) {
|
|
1379
|
-
t && e && !r.files[e] && (r.files[e] = {}, a.loadModule(t, function(t) {
|
|
1380
|
-
t && (r.files[e] = t, !t.snippets && t.snippetText && (t.snippets = r.parseSnippetFile(t.snippetText)), r.register(t.snippets || [], t.scope), t.includeScopes && (r.snippetMap[t.scope].includeScopes = t.includeScopes, t.includeScopes.forEach(function(e) {
|
|
1381
|
-
g("ace/mode/" + e);
|
|
1382
|
-
})));
|
|
1383
|
-
}));
|
|
1384
|
-
}, v = function(e) {
|
|
1385
|
-
var t = e.editor, n = t.completer && t.completer.activated;
|
|
1386
|
-
if (e.command.name === "backspace") n && !s.getCompletionPrefix(t) && t.completer.detach();
|
|
1387
|
-
else if (e.command.name === "insertstring" && !n) {
|
|
1388
|
-
y = e;
|
|
1389
|
-
var r = e.editor.$liveAutocompletionDelay;
|
|
1390
|
-
r ? b.delay(r) : x(e);
|
|
1391
|
-
}
|
|
1392
|
-
}, y, b = o.delayedCall(function() {
|
|
1393
|
-
x(y);
|
|
1394
|
-
}, 0), x = function(e) {
|
|
1395
|
-
var t = e.editor, n = s.getCompletionPrefix(t), r = e.args, a = s.triggerAutocomplete(t, r);
|
|
1396
|
-
if (n && n.length >= t.$liveAutocompletionThreshold || a) {
|
|
1397
|
-
var o = i.for(t);
|
|
1398
|
-
o.autoShown = !0, o.showPopup(t);
|
|
1399
|
-
}
|
|
1400
|
-
}, S = e("../editor").Editor;
|
|
1401
|
-
e("../config").defineOptions(S.prototype, "editor", {
|
|
1402
|
-
enableBasicAutocompletion: {
|
|
1403
|
-
set: function(e) {
|
|
1404
|
-
e ? (i.for(this), this.completers ||= Array.isArray(e) ? e : p, this.commands.addCommand(i.startCommand)) : this.commands.removeCommand(i.startCommand);
|
|
1405
|
-
},
|
|
1406
|
-
value: !1
|
|
1407
|
-
},
|
|
1408
|
-
enableLiveAutocompletion: {
|
|
1409
|
-
set: function(e) {
|
|
1410
|
-
e ? (this.completers ||= Array.isArray(e) ? e : p, this.commands.on("afterExec", v)) : this.commands.off("afterExec", v);
|
|
1411
|
-
},
|
|
1412
|
-
value: !1
|
|
1413
|
-
},
|
|
1414
|
-
liveAutocompletionDelay: { initialValue: 0 },
|
|
1415
|
-
liveAutocompletionThreshold: { initialValue: 0 },
|
|
1416
|
-
enableSnippets: {
|
|
1417
|
-
set: function(e) {
|
|
1418
|
-
e ? (this.commands.addCommand(m), this.on("changeMode", h), h(null, this)) : (this.commands.removeCommand(m), this.off("changeMode", h));
|
|
1419
|
-
},
|
|
1420
|
-
value: !1
|
|
1421
|
-
}
|
|
1422
|
-
}), t.MarkerGroup = c;
|
|
1423
|
-
}), (function() {
|
|
1424
|
-
ace.require(["ace/ext/language_tools"], function(n) {
|
|
1425
|
-
typeof t == "object" && typeof e == "object" && t && (t.exports = n);
|
|
1426
|
-
});
|
|
1427
|
-
})();
|
|
1428
|
-
})))(), r.default.config.setModuleUrl("ace/mode/yaml", "data:text/javascript;base64,YWNlLmRlZmluZSgiYWNlL21vZGUveWFtbF9oaWdobGlnaHRfcnVsZXMiLFsicmVxdWlyZSIsImV4cG9ydHMiLCJtb2R1bGUiLCJhY2UvbGliL29vcCIsImFjZS9tb2RlL3RleHRfaGlnaGxpZ2h0X3J1bGVzIl0sIGZ1bmN0aW9uKHJlcXVpcmUsIGV4cG9ydHMsIG1vZHVsZSl7InVzZSBzdHJpY3QiOwp2YXIgb29wID0gcmVxdWlyZSgiLi4vbGliL29vcCIpOwp2YXIgVGV4dEhpZ2hsaWdodFJ1bGVzID0gcmVxdWlyZSgiLi90ZXh0X2hpZ2hsaWdodF9ydWxlcyIpLlRleHRIaWdobGlnaHRSdWxlczsKdmFyIFlhbWxIaWdobGlnaHRSdWxlcyA9IGZ1bmN0aW9uICgpIHsKICAgIHRoaXMuJHJ1bGVzID0gewogICAgICAgICJzdGFydCI6IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdG9rZW46ICJjb21tZW50IiwKICAgICAgICAgICAgICAgIHJlZ2V4OiAiIy4qJCIKICAgICAgICAgICAgfSwgewogICAgICAgICAgICAgICAgdG9rZW46ICJsaXN0Lm1hcmt1cCIsCiAgICAgICAgICAgICAgICByZWdleDogL14oPzotezN9fFwuezN9KVxzKig/PSN8JCkvCiAgICAgICAgICAgIH0sIHsKICAgICAgICAgICAgICAgIHRva2VuOiAibGlzdC5tYXJrdXAiLAogICAgICAgICAgICAgICAgcmVnZXg6IC9eXHMqW1wtP10oPzokfFxzKS8KICAgICAgICAgICAgfSwgewogICAgICAgICAgICAgICAgdG9rZW46ICJjb25zdGFudCIsCiAgICAgICAgICAgICAgICByZWdleDogIiEhW1xcdy8vXSsiCiAgICAgICAgICAgIH0sIHsKICAgICAgICAgICAgICAgIHRva2VuOiAiY29uc3RhbnQubGFuZ3VhZ2UiLAogICAgICAgICAgICAgICAgcmVnZXg6ICJbJlxcKl1bYS16QS1aMC05LV9dKyIKICAgICAgICAgICAgfSwgewogICAgICAgICAgICAgICAgdG9rZW46IFsibWV0YS50YWciLCAia2V5d29yZCJdLAogICAgICAgICAgICAgICAgcmVnZXg6IC9eKFxzKlx3W15cczpdKj8pKDooPz1cc3wkKSkvCiAgICAgICAgICAgIH0sIHsKICAgICAgICAgICAgICAgIHRva2VuOiBbIm1ldGEudGFnIiwgImtleXdvcmQiXSwKICAgICAgICAgICAgICAgIHJlZ2V4OiAvKFx3W15cczpdKj8pKFxzKjooPz1cc3wkKSkvCiAgICAgICAgICAgIH0sIHsKICAgICAgICAgICAgICAgIHRva2VuOiAia2V5d29yZC5vcGVyYXRvciIsCiAgICAgICAgICAgICAgICByZWdleDogIjw8XFx3KjpcXHcqIgogICAgICAgICAgICB9LCB7CiAgICAgICAgICAgICAgICB0b2tlbjogImtleXdvcmQub3BlcmF0b3IiLAogICAgICAgICAgICAgICAgcmVnZXg6ICItXFxzKig/PVt7XSkiCiAgICAgICAgICAgIH0sIHsKICAgICAgICAgICAgICAgIHRva2VuOiAic3RyaW5nIiwgLy8gc2luZ2xlIGxpbmUKICAgICAgICAgICAgICAgIHJlZ2V4OiAnWyJdKD86KD86XFxcXC4pfCg/OlteIlxcXFxdKSkqP1siXScKICAgICAgICAgICAgfSwgewogICAgICAgICAgICAgICAgdG9rZW46ICJzdHJpbmciLCAvLyBtdWx0aSBsaW5lIHN0cmluZyBzdGFydAogICAgICAgICAgICAgICAgcmVnZXg6IC9bfD5dWy0rXGRdKig/OiR8XHMrKD86JHwjKSkvLAogICAgICAgICAgICAgICAgb25NYXRjaDogZnVuY3Rpb24gKHZhbCwgc3RhdGUsIHN0YWNrLCBsaW5lKSB7CiAgICAgICAgICAgICAgICAgICAgbGluZSA9IGxpbmUucmVwbGFjZSgvICMuKi8sICIiKTsKICAgICAgICAgICAgICAgICAgICB2YXIgaW5kZW50ID0gL14gKigoOlxzKik/LShccypbXnw+XSk/KT8vLmV4ZWMobGluZSlbMF0KICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xTXHMqJC8sICIiKS5sZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgdmFyIGluZGVudGF0aW9uSW5kaWNhdG9yID0gcGFyc2VJbnQoL1xkK1tccystXSokLy5leGVjKGxpbmUpKTsKICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZW50YXRpb25JbmRpY2F0b3IpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaW5kZW50ICs9IGluZGVudGF0aW9uSW5kaWNhdG9yIC0gMTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5uZXh0ID0gIm1sU3RyaW5nIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubmV4dCA9ICJtbFN0cmluZ1ByZSI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICghc3RhY2subGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0YWNrLnB1c2godGhpcy5uZXh0KTsKICAgICAgICAgICAgICAgICAgICAgICAgc3RhY2sucHVzaChpbmRlbnQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3RhY2tbMF0gPSB0aGlzLm5leHQ7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0YWNrWzFdID0gaW5kZW50OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50b2tlbjsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBuZXh0OiAibWxTdHJpbmciCiAgICAgICAgICAgIH0sIHsKICAgICAgICAgICAgICAgIHRva2VuOiAic3RyaW5nIiwgLy8gc2luZ2xlIHF1b3RlZCBzdHJpbmcKICAgICAgICAgICAgICAgIHJlZ2V4OiAiWyddKD86KD86XFxcXC4pfCg/OlteJ1xcXFxdKSkqP1snXSIKICAgICAgICAgICAgfSwgewogICAgICAgICAgICAgICAgdG9rZW46ICJjb25zdGFudC5udW1lcmljIiwgLy8gZmxvYXQKICAgICAgICAgICAgICAgIHJlZ2V4OiAvKFxifFsrXC1cLl0pW1xkX10rKD86KD86XC5bXGRfXSopPyg/OltlRV1bK1wtXT9bXGRfXSspPykoPz1bXlxkLVx3XXwkKSQvCiAgICAgICAgICAgIH0sIHsKICAgICAgICAgICAgICAgIHRva2VuOiAiY29uc3RhbnQubnVtZXJpYyIsIC8vIG90aGVyIG51bWJlcgogICAgICAgICAgICAgICAgcmVnZXg6IC9bK1wtXT9cLmluZlxifE5hTlxifDB4W1xkQS1GYS1mX10rfDBiWzEwX10rLwogICAgICAgICAgICB9LCB7CiAgICAgICAgICAgICAgICB0b2tlbjogImNvbnN0YW50Lmxhbmd1YWdlLmJvb2xlYW4iLAogICAgICAgICAgICAgICAgcmVnZXg6ICJcXGIoPzp0cnVlfGZhbHNlfFRSVUV8RkFMU0V8VHJ1ZXxGYWxzZXx5ZXN8bm8pXFxiIgogICAgICAgICAgICB9LCB7CiAgICAgICAgICAgICAgICB0b2tlbjogInBhcmVuLmxwYXJlbiIsCiAgICAgICAgICAgICAgICByZWdleDogIltbKHtdIgogICAgICAgICAgICB9LCB7CiAgICAgICAgICAgICAgICB0b2tlbjogInBhcmVuLnJwYXJlbiIsCiAgICAgICAgICAgICAgICByZWdleDogIltcXF0pfV0iCiAgICAgICAgICAgIH0sIHsKICAgICAgICAgICAgICAgIHRva2VuOiAidGV4dCIsCiAgICAgICAgICAgICAgICByZWdleDogL1teXHMsOlxbXF1ce1x9XSsvCiAgICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJtbFN0cmluZ1ByZSI6IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdG9rZW46ICJpbmRlbnQiLAogICAgICAgICAgICAgICAgcmVnZXg6IC9eICokLwogICAgICAgICAgICB9LCB7CiAgICAgICAgICAgICAgICB0b2tlbjogImluZGVudCIsCiAgICAgICAgICAgICAgICByZWdleDogL14gKi8sCiAgICAgICAgICAgICAgICBvbk1hdGNoOiBmdW5jdGlvbiAodmFsLCBzdGF0ZSwgc3RhY2spIHsKICAgICAgICAgICAgICAgICAgICB2YXIgY3VySW5kZW50ID0gc3RhY2tbMV07CiAgICAgICAgICAgICAgICAgICAgaWYgKGN1ckluZGVudCA+PSB2YWwubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubmV4dCA9ICJzdGFydCI7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0YWNrLnNoaWZ0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0YWNrLnNoaWZ0KCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBzdGFja1sxXSA9IHZhbC5sZW5ndGggLSAxOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm5leHQgPSBzdGFja1swXSA9ICJtbFN0cmluZyI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnRva2VuOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIG5leHQ6ICJtbFN0cmluZyIKICAgICAgICAgICAgfSwgewogICAgICAgICAgICAgICAgZGVmYXVsdFRva2VuOiAic3RyaW5nIgogICAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAibWxTdHJpbmciOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRva2VuOiAiaW5kZW50IiwKICAgICAgICAgICAgICAgIHJlZ2V4OiAvXiAqJC8KICAgICAgICAgICAgfSwgewogICAgICAgICAgICAgICAgdG9rZW46ICJpbmRlbnQiLAogICAgICAgICAgICAgICAgcmVnZXg6IC9eICovLAogICAgICAgICAgICAgICAgb25NYXRjaDogZnVuY3Rpb24gKHZhbCwgc3RhdGUsIHN0YWNrKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGN1ckluZGVudCA9IHN0YWNrWzFdOwogICAgICAgICAgICAgICAgICAgIGlmIChjdXJJbmRlbnQgPj0gdmFsLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm5leHQgPSAic3RhcnQiOwogICAgICAgICAgICAgICAgICAgICAgICBzdGFjay5zcGxpY2UoMCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm5leHQgPSAibWxTdHJpbmciOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50b2tlbjsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBuZXh0OiAibWxTdHJpbmciCiAgICAgICAgICAgIH0sIHsKICAgICAgICAgICAgICAgIHRva2VuOiAic3RyaW5nIiwKICAgICAgICAgICAgICAgIHJlZ2V4OiAnLisnCiAgICAgICAgICAgIH0KICAgICAgICBdCiAgICB9OwogICAgdGhpcy5ub3JtYWxpemVSdWxlcygpOwp9Owpvb3AuaW5oZXJpdHMoWWFtbEhpZ2hsaWdodFJ1bGVzLCBUZXh0SGlnaGxpZ2h0UnVsZXMpOwpleHBvcnRzLllhbWxIaWdobGlnaHRSdWxlcyA9IFlhbWxIaWdobGlnaHRSdWxlczsKCn0pOwoKYWNlLmRlZmluZSgiYWNlL21vZGUvbWF0Y2hpbmdfYnJhY2Vfb3V0ZGVudCIsWyJyZXF1aXJlIiwiZXhwb3J0cyIsIm1vZHVsZSIsImFjZS9yYW5nZSJdLCBmdW5jdGlvbihyZXF1aXJlLCBleHBvcnRzLCBtb2R1bGUpeyJ1c2Ugc3RyaWN0IjsKdmFyIFJhbmdlID0gcmVxdWlyZSgiLi4vcmFuZ2UiKS5SYW5nZTsKdmFyIE1hdGNoaW5nQnJhY2VPdXRkZW50ID0gZnVuY3Rpb24gKCkgeyB9OwooZnVuY3Rpb24gKCkgewogICAgdGhpcy5jaGVja091dGRlbnQgPSBmdW5jdGlvbiAobGluZSwgaW5wdXQpIHsKICAgICAgICBpZiAoIS9eXHMrJC8udGVzdChsaW5lKSkKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIHJldHVybiAvXlxzKlx9Ly50ZXN0KGlucHV0KTsKICAgIH07CiAgICB0aGlzLmF1dG9PdXRkZW50ID0gZnVuY3Rpb24gKGRvYywgcm93KSB7CiAgICAgICAgdmFyIGxpbmUgPSBkb2MuZ2V0TGluZShyb3cpOwogICAgICAgIHZhciBtYXRjaCA9IGxpbmUubWF0Y2goL14oXHMqXH0pLyk7CiAgICAgICAgaWYgKCFtYXRjaCkKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgdmFyIGNvbHVtbiA9IG1hdGNoWzFdLmxlbmd0aDsKICAgICAgICB2YXIgb3BlbkJyYWNlUG9zID0gZG9jLmZpbmRNYXRjaGluZ0JyYWNrZXQoeyByb3c6IHJvdywgY29sdW1uOiBjb2x1bW4gfSk7CiAgICAgICAgaWYgKCFvcGVuQnJhY2VQb3MgfHwgb3BlbkJyYWNlUG9zLnJvdyA9PSByb3cpCiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIHZhciBpbmRlbnQgPSB0aGlzLiRnZXRJbmRlbnQoZG9jLmdldExpbmUob3BlbkJyYWNlUG9zLnJvdykpOwogICAgICAgIGRvYy5yZXBsYWNlKG5ldyBSYW5nZShyb3csIDAsIHJvdywgY29sdW1uIC0gMSksIGluZGVudCk7CiAgICB9OwogICAgdGhpcy4kZ2V0SW5kZW50ID0gZnVuY3Rpb24gKGxpbmUpIHsKICAgICAgICByZXR1cm4gbGluZS5tYXRjaCgvXlxzKi8pWzBdOwogICAgfTsKfSkuY2FsbChNYXRjaGluZ0JyYWNlT3V0ZGVudC5wcm90b3R5cGUpOwpleHBvcnRzLk1hdGNoaW5nQnJhY2VPdXRkZW50ID0gTWF0Y2hpbmdCcmFjZU91dGRlbnQ7Cgp9KTsKCmFjZS5kZWZpbmUoImFjZS9tb2RlL2ZvbGRpbmcvY29mZmVlIixbInJlcXVpcmUiLCJleHBvcnRzIiwibW9kdWxlIiwiYWNlL2xpYi9vb3AiLCJhY2UvbW9kZS9mb2xkaW5nL2ZvbGRfbW9kZSIsImFjZS9yYW5nZSJdLCBmdW5jdGlvbihyZXF1aXJlLCBleHBvcnRzLCBtb2R1bGUpeyJ1c2Ugc3RyaWN0IjsKdmFyIG9vcCA9IHJlcXVpcmUoIi4uLy4uL2xpYi9vb3AiKTsKdmFyIEJhc2VGb2xkTW9kZSA9IHJlcXVpcmUoIi4vZm9sZF9tb2RlIikuRm9sZE1vZGU7CnZhciBSYW5nZSA9IHJlcXVpcmUoIi4uLy4uL3JhbmdlIikuUmFuZ2U7CnZhciBGb2xkTW9kZSA9IGV4cG9ydHMuRm9sZE1vZGUgPSBmdW5jdGlvbiAoKSB7IH07Cm9vcC5pbmhlcml0cyhGb2xkTW9kZSwgQmFzZUZvbGRNb2RlKTsKKGZ1bmN0aW9uICgpIHsKICAgIHRoaXMuY29tbWVudEJsb2NrID0gZnVuY3Rpb24gKHNlc3Npb24sIHJvdykgewogICAgICAgIHZhciByZSA9IC9cUy87CiAgICAgICAgdmFyIGxpbmUgPSBzZXNzaW9uLmdldExpbmUocm93KTsKICAgICAgICB2YXIgc3RhcnRMZXZlbCA9IGxpbmUuc2VhcmNoKHJlKTsKICAgICAgICBpZiAoc3RhcnRMZXZlbCA9PSAtMSB8fCBsaW5lW3N0YXJ0TGV2ZWxdICE9ICIjIikKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIHZhciBzdGFydENvbHVtbiA9IGxpbmUubGVuZ3RoOwogICAgICAgIHZhciBtYXhSb3cgPSBzZXNzaW9uLmdldExlbmd0aCgpOwogICAgICAgIHZhciBzdGFydFJvdyA9IHJvdzsKICAgICAgICB2YXIgZW5kUm93ID0gcm93OwogICAgICAgIHdoaWxlICgrK3JvdyA8IG1heFJvdykgewogICAgICAgICAgICBsaW5lID0gc2Vzc2lvbi5nZXRMaW5lKHJvdyk7CiAgICAgICAgICAgIHZhciBsZXZlbCA9IGxpbmUuc2VhcmNoKHJlKTsKICAgICAgICAgICAgaWYgKGxldmVsID09IC0xKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIGlmIChsaW5lW2xldmVsXSAhPSAiIyIpCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZW5kUm93ID0gcm93OwogICAgICAgIH0KICAgICAgICBpZiAoZW5kUm93ID4gc3RhcnRSb3cpIHsKICAgICAgICAgICAgdmFyIGVuZENvbHVtbiA9IHNlc3Npb24uZ2V0TGluZShlbmRSb3cpLmxlbmd0aDsKICAgICAgICAgICAgcmV0dXJuIG5ldyBSYW5nZShzdGFydFJvdywgc3RhcnRDb2x1bW4sIGVuZFJvdywgZW5kQ29sdW1uKTsKICAgICAgICB9CiAgICB9OwogICAgdGhpcy5nZXRGb2xkV2lkZ2V0UmFuZ2UgPSBmdW5jdGlvbiAoc2Vzc2lvbiwgZm9sZFN0eWxlLCByb3cpIHsKICAgICAgICB2YXIgcmFuZ2UgPSB0aGlzLmluZGVudGF0aW9uQmxvY2soc2Vzc2lvbiwgcm93KTsKICAgICAgICBpZiAocmFuZ2UpCiAgICAgICAgICAgIHJldHVybiByYW5nZTsKICAgICAgICByYW5nZSA9IHRoaXMuY29tbWVudEJsb2NrKHNlc3Npb24sIHJvdyk7CiAgICAgICAgaWYgKHJhbmdlKQogICAgICAgICAgICByZXR1cm4gcmFuZ2U7CiAgICB9OwogICAgdGhpcy5nZXRGb2xkV2lkZ2V0ID0gZnVuY3Rpb24gKHNlc3Npb24sIGZvbGRTdHlsZSwgcm93KSB7CiAgICAgICAgdmFyIGxpbmUgPSBzZXNzaW9uLmdldExpbmUocm93KTsKICAgICAgICB2YXIgaW5kZW50ID0gbGluZS5zZWFyY2goL1xTLyk7CiAgICAgICAgdmFyIG5leHQgPSBzZXNzaW9uLmdldExpbmUocm93ICsgMSk7CiAgICAgICAgdmFyIHByZXYgPSBzZXNzaW9uLmdldExpbmUocm93IC0gMSk7CiAgICAgICAgdmFyIHByZXZJbmRlbnQgPSBwcmV2LnNlYXJjaCgvXFMvKTsKICAgICAgICB2YXIgbmV4dEluZGVudCA9IG5leHQuc2VhcmNoKC9cUy8pOwogICAgICAgIGlmIChpbmRlbnQgPT0gLTEpIHsKICAgICAgICAgICAgc2Vzc2lvbi5mb2xkV2lkZ2V0c1tyb3cgLSAxXSA9IHByZXZJbmRlbnQgIT0gLTEgJiYgcHJldkluZGVudCA8IG5leHRJbmRlbnQgPyAic3RhcnQiIDogIiI7CiAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICB9CiAgICAgICAgaWYgKHByZXZJbmRlbnQgPT0gLTEpIHsKICAgICAgICAgICAgaWYgKGluZGVudCA9PSBuZXh0SW5kZW50ICYmIGxpbmVbaW5kZW50XSA9PSAiIyIgJiYgbmV4dFtpbmRlbnRdID09ICIjIikgewogICAgICAgICAgICAgICAgc2Vzc2lvbi5mb2xkV2lkZ2V0c1tyb3cgLSAxXSA9ICIiOwogICAgICAgICAgICAgICAgc2Vzc2lvbi5mb2xkV2lkZ2V0c1tyb3cgKyAxXSA9ICIiOwogICAgICAgICAgICAgICAgcmV0dXJuICJzdGFydCI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAocHJldkluZGVudCA9PSBpbmRlbnQgJiYgbGluZVtpbmRlbnRdID09ICIjIiAmJiBwcmV2W2luZGVudF0gPT0gIiMiKSB7CiAgICAgICAgICAgIGlmIChzZXNzaW9uLmdldExpbmUocm93IC0gMikuc2VhcmNoKC9cUy8pID09IC0xKSB7CiAgICAgICAgICAgICAgICBzZXNzaW9uLmZvbGRXaWRnZXRzW3JvdyAtIDFdID0gInN0YXJ0IjsKICAgICAgICAgICAgICAgIHNlc3Npb24uZm9sZFdpZGdldHNbcm93ICsgMV0gPSAiIjsKICAgICAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAocHJldkluZGVudCAhPSAtMSAmJiBwcmV2SW5kZW50IDwgaW5kZW50KQogICAgICAgICAgICBzZXNzaW9uLmZvbGRXaWRnZXRzW3JvdyAtIDFdID0gInN0YXJ0IjsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHNlc3Npb24uZm9sZFdpZGdldHNbcm93IC0gMV0gPSAiIjsKICAgICAgICBpZiAoaW5kZW50IDwgbmV4dEluZGVudCkKICAgICAgICAgICAgcmV0dXJuICJzdGFydCI7CiAgICAgICAgZWxzZQogICAgICAgICAgICByZXR1cm4gIiI7CiAgICB9Owp9KS5jYWxsKEZvbGRNb2RlLnByb3RvdHlwZSk7Cgp9KTsKCmFjZS5kZWZpbmUoImFjZS9tb2RlL2ZvbGRpbmcveWFtbCIsWyJyZXF1aXJlIiwiZXhwb3J0cyIsIm1vZHVsZSIsImFjZS9saWIvb29wIiwiYWNlL21vZGUvZm9sZGluZy9jb2ZmZWUiLCJhY2UvcmFuZ2UiXSwgZnVuY3Rpb24ocmVxdWlyZSwgZXhwb3J0cywgbW9kdWxlKXsidXNlIHN0cmljdCI7CnZhciBvb3AgPSByZXF1aXJlKCIuLi8uLi9saWIvb29wIik7CnZhciBDb2ZmZWVGb2xkTW9kZSA9IHJlcXVpcmUoIi4vY29mZmVlIikuRm9sZE1vZGU7CnZhciBSYW5nZSA9IHJlcXVpcmUoIi4uLy4uL3JhbmdlIikuUmFuZ2U7CnZhciBGb2xkTW9kZSA9IGV4cG9ydHMuRm9sZE1vZGUgPSBmdW5jdGlvbiAoKSB7IH07Cm9vcC5pbmhlcml0cyhGb2xkTW9kZSwgQ29mZmVlRm9sZE1vZGUpOwooZnVuY3Rpb24gKCkgewogICAgdGhpcy5nZXRGb2xkV2lkZ2V0UmFuZ2UgPSBmdW5jdGlvbiAoc2Vzc2lvbiwgZm9sZFN0eWxlLCByb3cpIHsKICAgICAgICB2YXIgcmUgPSAvXFMvOwogICAgICAgIHZhciBsaW5lID0gc2Vzc2lvbi5nZXRMaW5lKHJvdyk7CiAgICAgICAgdmFyIHN0YXJ0TGV2ZWwgPSBsaW5lLnNlYXJjaChyZSk7CiAgICAgICAgdmFyIGlzQ29tbWVudEZvbGQgPSBsaW5lW3N0YXJ0TGV2ZWxdID09PSAiIyI7CiAgICAgICAgdmFyIGlzRGFzaEZvbGQgPSBsaW5lW3N0YXJ0TGV2ZWxdID09PSAiLSI7CiAgICAgICAgaWYgKHN0YXJ0TGV2ZWwgPT0gLTEpCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB2YXIgc3RhcnRDb2x1bW4gPSBsaW5lLmxlbmd0aDsKICAgICAgICB2YXIgbWF4Um93ID0gc2Vzc2lvbi5nZXRMZW5ndGgoKTsKICAgICAgICB2YXIgc3RhcnRSb3cgPSByb3c7CiAgICAgICAgdmFyIGVuZFJvdyA9IHJvdzsKICAgICAgICBpZiAoaXNDb21tZW50Rm9sZCkgewogICAgICAgICAgICB2YXIgcmFuZ2UgPSB0aGlzLmNvbW1lbnRCbG9jayhzZXNzaW9uLCByb3cpOwogICAgICAgICAgICBpZiAocmFuZ2UpCiAgICAgICAgICAgICAgICByZXR1cm4gcmFuZ2U7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKGlzRGFzaEZvbGQpIHsKICAgICAgICAgICAgdmFyIHJhbmdlID0gdGhpcy5pbmRlbnRhdGlvbkJsb2NrKHNlc3Npb24sIHJvdyk7CiAgICAgICAgICAgIGlmIChyYW5nZSkKICAgICAgICAgICAgICAgIHJldHVybiByYW5nZTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIHdoaWxlICgrK3JvdyA8IG1heFJvdykgewogICAgICAgICAgICAgICAgdmFyIGxpbmUgPSBzZXNzaW9uLmdldExpbmUocm93KTsKICAgICAgICAgICAgICAgIHZhciBsZXZlbCA9IGxpbmUuc2VhcmNoKHJlKTsKICAgICAgICAgICAgICAgIGlmIChsZXZlbCA9PSAtMSkKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIGlmIChsZXZlbCA8PSBzdGFydExldmVsICYmIGxpbmVbc3RhcnRMZXZlbF0gIT09ICctJykgewogICAgICAgICAgICAgICAgICAgIHZhciB0b2tlbiA9IHNlc3Npb24uZ2V0VG9rZW5BdChyb3csIDApOwogICAgICAgICAgICAgICAgICAgIGlmICghdG9rZW4gfHwgdG9rZW4udHlwZSAhPT0gInN0cmluZyIpCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZW5kUm93ID0gcm93OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChlbmRSb3cgPiBzdGFydFJvdykgewogICAgICAgICAgICB2YXIgZW5kQ29sdW1uID0gc2Vzc2lvbi5nZXRMaW5lKGVuZFJvdykubGVuZ3RoOwogICAgICAgICAgICByZXR1cm4gbmV3IFJhbmdlKHN0YXJ0Um93LCBzdGFydENvbHVtbiwgZW5kUm93LCBlbmRDb2x1bW4pOwogICAgICAgIH0KICAgIH07CiAgICB0aGlzLmdldEZvbGRXaWRnZXQgPSBmdW5jdGlvbiAoc2Vzc2lvbiwgZm9sZFN0eWxlLCByb3cpIHsKICAgICAgICB2YXIgbGluZSA9IHNlc3Npb24uZ2V0TGluZShyb3cpOwogICAgICAgIHZhciBpbmRlbnQgPSBsaW5lLnNlYXJjaCgvXFMvKTsKICAgICAgICB2YXIgbmV4dCA9IHNlc3Npb24uZ2V0TGluZShyb3cgKyAxKTsKICAgICAgICB2YXIgcHJldiA9IHNlc3Npb24uZ2V0TGluZShyb3cgLSAxKTsKICAgICAgICB2YXIgcHJldkluZGVudCA9IHByZXYuc2VhcmNoKC9cUy8pOwogICAgICAgIHZhciBuZXh0SW5kZW50ID0gbmV4dC5zZWFyY2goL1xTLyk7CiAgICAgICAgdmFyIGxpbmVTdGFydHNXaXRoRGFzaCA9IGxpbmVbaW5kZW50XSA9PT0gJy0nOwogICAgICAgIGlmIChpbmRlbnQgPT0gLTEpIHsKICAgICAgICAgICAgc2Vzc2lvbi5mb2xkV2lkZ2V0c1tyb3cgLSAxXSA9IHByZXZJbmRlbnQgIT0gLTEgJiYgcHJldkluZGVudCA8IG5leHRJbmRlbnQgPyAic3RhcnQiIDogIiI7CiAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICB9CiAgICAgICAgaWYgKHByZXZJbmRlbnQgPT0gLTEpIHsKICAgICAgICAgICAgaWYgKGluZGVudCA9PSBuZXh0SW5kZW50ICYmIGxpbmVbaW5kZW50XSA9PSAiIyIgJiYgbmV4dFtpbmRlbnRdID09ICIjIikgewogICAgICAgICAgICAgICAgc2Vzc2lvbi5mb2xkV2lkZ2V0c1tyb3cgLSAxXSA9ICIiOwogICAgICAgICAgICAgICAgc2Vzc2lvbi5mb2xkV2lkZ2V0c1tyb3cgKyAxXSA9ICIiOwogICAgICAgICAgICAgICAgcmV0dXJuICJzdGFydCI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAocHJldkluZGVudCA9PSBpbmRlbnQgJiYgbGluZVtpbmRlbnRdID09ICIjIiAmJiBwcmV2W2luZGVudF0gPT0gIiMiKSB7CiAgICAgICAgICAgIGlmIChzZXNzaW9uLmdldExpbmUocm93IC0gMikuc2VhcmNoKC9cUy8pID09IC0xKSB7CiAgICAgICAgICAgICAgICBzZXNzaW9uLmZvbGRXaWRnZXRzW3JvdyAtIDFdID0gInN0YXJ0IjsKICAgICAgICAgICAgICAgIHNlc3Npb24uZm9sZFdpZGdldHNbcm93ICsgMV0gPSAiIjsKICAgICAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAocHJldkluZGVudCAhPSAtMSAmJiBwcmV2SW5kZW50IDwgaW5kZW50KSB7CiAgICAgICAgICAgIHNlc3Npb24uZm9sZFdpZGdldHNbcm93IC0gMV0gPSAic3RhcnQiOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChwcmV2SW5kZW50ICE9IC0xICYmIChwcmV2SW5kZW50ID09IGluZGVudCAmJiBsaW5lU3RhcnRzV2l0aERhc2gpKSB7CiAgICAgICAgICAgIHNlc3Npb24uZm9sZFdpZGdldHNbcm93IC0gMV0gPSAic3RhcnQiOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgc2Vzc2lvbi5mb2xkV2lkZ2V0c1tyb3cgLSAxXSA9ICIiOwogICAgICAgIH0KICAgICAgICBpZiAoaW5kZW50IDwgbmV4dEluZGVudCkKICAgICAgICAgICAgcmV0dXJuICJzdGFydCI7CiAgICAgICAgZWxzZQogICAgICAgICAgICByZXR1cm4gIiI7CiAgICB9Owp9KS5jYWxsKEZvbGRNb2RlLnByb3RvdHlwZSk7Cgp9KTsKCmFjZS5kZWZpbmUoImFjZS9tb2RlL3lhbWwiLFsicmVxdWlyZSIsImV4cG9ydHMiLCJtb2R1bGUiLCJhY2UvbGliL29vcCIsImFjZS9tb2RlL3RleHQiLCJhY2UvbW9kZS95YW1sX2hpZ2hsaWdodF9ydWxlcyIsImFjZS9tb2RlL21hdGNoaW5nX2JyYWNlX291dGRlbnQiLCJhY2UvbW9kZS9mb2xkaW5nL3lhbWwiLCJhY2Uvd29ya2VyL3dvcmtlcl9jbGllbnQiXSwgZnVuY3Rpb24ocmVxdWlyZSwgZXhwb3J0cywgbW9kdWxlKXsidXNlIHN0cmljdCI7CnZhciBvb3AgPSByZXF1aXJlKCIuLi9saWIvb29wIik7CnZhciBUZXh0TW9kZSA9IHJlcXVpcmUoIi4vdGV4dCIpLk1vZGU7CnZhciBZYW1sSGlnaGxpZ2h0UnVsZXMgPSByZXF1aXJlKCIuL3lhbWxfaGlnaGxpZ2h0X3J1bGVzIikuWWFtbEhpZ2hsaWdodFJ1bGVzOwp2YXIgTWF0Y2hpbmdCcmFjZU91dGRlbnQgPSByZXF1aXJlKCIuL21hdGNoaW5nX2JyYWNlX291dGRlbnQiKS5NYXRjaGluZ0JyYWNlT3V0ZGVudDsKdmFyIEZvbGRNb2RlID0gcmVxdWlyZSgiLi9mb2xkaW5nL3lhbWwiKS5Gb2xkTW9kZTsKdmFyIFdvcmtlckNsaWVudCA9IHJlcXVpcmUoIi4uL3dvcmtlci93b3JrZXJfY2xpZW50IikuV29ya2VyQ2xpZW50Owp2YXIgTW9kZSA9IGZ1bmN0aW9uICgpIHsKICAgIHRoaXMuSGlnaGxpZ2h0UnVsZXMgPSBZYW1sSGlnaGxpZ2h0UnVsZXM7CiAgICB0aGlzLiRvdXRkZW50ID0gbmV3IE1hdGNoaW5nQnJhY2VPdXRkZW50KCk7CiAgICB0aGlzLmZvbGRpbmdSdWxlcyA9IG5ldyBGb2xkTW9kZSgpOwogICAgdGhpcy4kYmVoYXZpb3VyID0gdGhpcy4kZGVmYXVsdEJlaGF2aW91cjsKfTsKb29wLmluaGVyaXRzKE1vZGUsIFRleHRNb2RlKTsKKGZ1bmN0aW9uICgpIHsKICAgIHRoaXMubGluZUNvbW1lbnRTdGFydCA9IFsiIyJdOwogICAgdGhpcy5nZXROZXh0TGluZUluZGVudCA9IGZ1bmN0aW9uIChzdGF0ZSwgbGluZSwgdGFiKSB7CiAgICAgICAgdmFyIGluZGVudCA9IHRoaXMuJGdldEluZGVudChsaW5lKTsKICAgICAgICBpZiAoc3RhdGUgPT0gInN0YXJ0IikgewogICAgICAgICAgICB2YXIgbWF0Y2ggPSBsaW5lLm1hdGNoKC9eLipbXHtcKFxbXVxzKiQvKTsKICAgICAgICAgICAgaWYgKG1hdGNoKSB7CiAgICAgICAgICAgICAgICBpbmRlbnQgKz0gdGFiOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbmRlbnQ7CiAgICB9OwogICAgdGhpcy5jaGVja091dGRlbnQgPSBmdW5jdGlvbiAoc3RhdGUsIGxpbmUsIGlucHV0KSB7CiAgICAgICAgcmV0dXJuIHRoaXMuJG91dGRlbnQuY2hlY2tPdXRkZW50KGxpbmUsIGlucHV0KTsKICAgIH07CiAgICB0aGlzLmF1dG9PdXRkZW50ID0gZnVuY3Rpb24gKHN0YXRlLCBkb2MsIHJvdykgewogICAgICAgIHRoaXMuJG91dGRlbnQuYXV0b091dGRlbnQoZG9jLCByb3cpOwogICAgfTsKICAgIHRoaXMuY3JlYXRlV29ya2VyID0gZnVuY3Rpb24gKHNlc3Npb24pIHsKICAgICAgICB2YXIgd29ya2VyID0gbmV3IFdvcmtlckNsaWVudChbImFjZSJdLCAiYWNlL21vZGUveWFtbF93b3JrZXIiLCAiWWFtbFdvcmtlciIpOwogICAgICAgIHdvcmtlci5hdHRhY2hUb0RvY3VtZW50KHNlc3Npb24uZ2V0RG9jdW1lbnQoKSk7CiAgICAgICAgd29ya2VyLm9uKCJhbm5vdGF0ZSIsIGZ1bmN0aW9uIChyZXN1bHRzKSB7CiAgICAgICAgICAgIHNlc3Npb24uc2V0QW5ub3RhdGlvbnMocmVzdWx0cy5kYXRhKTsKICAgICAgICB9KTsKICAgICAgICB3b3JrZXIub24oInRlcm1pbmF0ZSIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgc2Vzc2lvbi5jbGVhckFubm90YXRpb25zKCk7CiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIHdvcmtlcjsKICAgIH07CiAgICB0aGlzLiRpZCA9ICJhY2UvbW9kZS95YW1sIjsKfSkuY2FsbChNb2RlLnByb3RvdHlwZSk7CmV4cG9ydHMuTW9kZSA9IE1vZGU7Cgp9KTsgICAgICAgICAgICAgICAgKGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgIGFjZS5yZXF1aXJlKFsiYWNlL21vZGUveWFtbCJdLCBmdW5jdGlvbihtKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbW9kdWxlID09ICJvYmplY3QiICYmIHR5cGVvZiBleHBvcnRzID09ICJvYmplY3QiICYmIG1vZHVsZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBtOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB9KSgpOwogICAgICAgICAgICA="), r.default.config.setModuleUrl("ace/theme/twilight", "data:text/javascript;base64,YWNlLmRlZmluZSgiYWNlL3RoZW1lL3R3aWxpZ2h0LWNzcyIsWyJyZXF1aXJlIiwiZXhwb3J0cyIsIm1vZHVsZSJdLCBmdW5jdGlvbihyZXF1aXJlLCBleHBvcnRzLCBtb2R1bGUpe21vZHVsZS5leHBvcnRzID0gIi5hY2UtdHdpbGlnaHQgLmFjZV9ndXR0ZXIge1xuICBiYWNrZ3JvdW5kOiAjMjMyMzIzO1xuICBjb2xvcjogI0UyRTJFMlxufVxuXG4uYWNlLXR3aWxpZ2h0IC5hY2VfcHJpbnQtbWFyZ2luIHtcbiAgd2lkdGg6IDFweDtcbiAgYmFja2dyb3VuZDogIzIzMjMyM1xufVxuXG4uYWNlLXR3aWxpZ2h0IHtcbiAgYmFja2dyb3VuZC1jb2xvcjogIzE0MTQxNDtcbiAgY29sb3I6ICNGOEY4Rjhcbn1cblxuLmFjZS10d2lsaWdodCAuYWNlX2N1cnNvciB7XG4gIGNvbG9yOiAjQTdBN0E3XG59XG5cbi5hY2UtdHdpbGlnaHQgLmFjZV9tYXJrZXItbGF5ZXIgLmFjZV9zZWxlY3Rpb24ge1xuICBiYWNrZ3JvdW5kOiByZ2JhKDIyMSwgMjQwLCAyNTUsIDAuMjApXG59XG5cbi5hY2UtdHdpbGlnaHQuYWNlX211bHRpc2VsZWN0IC5hY2Vfc2VsZWN0aW9uLmFjZV9zdGFydCB7XG4gIGJveC1zaGFkb3c6IDAgMCAzcHggMHB4ICMxNDE0MTQ7XG59XG5cbi5hY2UtdHdpbGlnaHQgLmFjZV9tYXJrZXItbGF5ZXIgLmFjZV9zdGVwIHtcbiAgYmFja2dyb3VuZDogcmdiKDEwMiwgODIsIDApXG59XG5cbi5hY2UtdHdpbGlnaHQgLmFjZV9tYXJrZXItbGF5ZXIgLmFjZV9icmFja2V0IHtcbiAgbWFyZ2luOiAtMXB4IDAgMCAtMXB4O1xuICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMjUpXG59XG5cbi5hY2UtdHdpbGlnaHQgLmFjZV9tYXJrZXItbGF5ZXIgLmFjZV9hY3RpdmUtbGluZSB7XG4gIGJhY2tncm91bmQ6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4wMzEpXG59XG5cbi5hY2UtdHdpbGlnaHQgLmFjZV9ndXR0ZXItYWN0aXZlLWxpbmUge1xuICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMDMxKVxufVxuXG4uYWNlLXR3aWxpZ2h0IC5hY2VfbWFya2VyLWxheWVyIC5hY2Vfc2VsZWN0ZWQtd29yZCB7XG4gIGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoMjIxLCAyNDAsIDI1NSwgMC4yMClcbn1cblxuLmFjZS10d2lsaWdodCAuYWNlX2ludmlzaWJsZSB7XG4gIGNvbG9yOiByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMjUpXG59XG5cbi5hY2UtdHdpbGlnaHQgLmFjZV9rZXl3b3JkLFxuLmFjZS10d2lsaWdodCAuYWNlX21ldGEge1xuICBjb2xvcjogI0NEQTg2OVxufVxuXG4uYWNlLXR3aWxpZ2h0IC5hY2VfY29uc3RhbnQsXG4uYWNlLXR3aWxpZ2h0IC5hY2VfY29uc3RhbnQuYWNlX2NoYXJhY3Rlcixcbi5hY2UtdHdpbGlnaHQgLmFjZV9jb25zdGFudC5hY2VfY2hhcmFjdGVyLmFjZV9lc2NhcGUsXG4uYWNlLXR3aWxpZ2h0IC5hY2VfY29uc3RhbnQuYWNlX290aGVyLFxuLmFjZS10d2lsaWdodCAuYWNlX2hlYWRpbmcsXG4uYWNlLXR3aWxpZ2h0IC5hY2VfbWFya3VwLmFjZV9oZWFkaW5nLFxuLmFjZS10d2lsaWdodCAuYWNlX3N1cHBvcnQuYWNlX2NvbnN0YW50IHtcbiAgY29sb3I6ICNDRjZBNENcbn1cblxuLmFjZS10d2lsaWdodCAuYWNlX2ludmFsaWQuYWNlX2lsbGVnYWwge1xuICBjb2xvcjogI0Y4RjhGODtcbiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSg4NiwgNDUsIDg2LCAwLjc1KVxufVxuXG4uYWNlLXR3aWxpZ2h0IC5hY2VfaW52YWxpZC5hY2VfZGVwcmVjYXRlZCB7XG4gIHRleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lO1xuICBmb250LXN0eWxlOiBpdGFsaWM7XG4gIGNvbG9yOiAjRDJBOEExXG59XG5cbi5hY2UtdHdpbGlnaHQgLmFjZV9zdXBwb3J0IHtcbiAgY29sb3I6ICM5Qjg1OURcbn1cblxuLmFjZS10d2lsaWdodCAuYWNlX2ZvbGQge1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjQUM4ODVCO1xuICBib3JkZXItY29sb3I6ICNGOEY4Rjhcbn1cblxuLmFjZS10d2lsaWdodCAuYWNlX3N1cHBvcnQuYWNlX2Z1bmN0aW9uIHtcbiAgY29sb3I6ICNEQUQwODVcbn1cblxuLmFjZS10d2lsaWdodCAuYWNlX2xpc3QsXG4uYWNlLXR3aWxpZ2h0IC5hY2VfbWFya3VwLmFjZV9saXN0LFxuLmFjZS10d2lsaWdodCAuYWNlX3N0b3JhZ2Uge1xuICBjb2xvcjogI0Y5RUU5OFxufVxuXG4uYWNlLXR3aWxpZ2h0IC5hY2VfZW50aXR5LmFjZV9uYW1lLmFjZV9mdW5jdGlvbixcbi5hY2UtdHdpbGlnaHQgLmFjZV9tZXRhLmFjZV90YWcge1xuICBjb2xvcjogI0FDODg1QlxufVxuXG4uYWNlLXR3aWxpZ2h0IC5hY2Vfc3RyaW5nIHtcbiAgY29sb3I6ICM4RjlENkFcbn1cblxuLmFjZS10d2lsaWdodCAuYWNlX3N0cmluZy5hY2VfcmVnZXhwIHtcbiAgY29sb3I6ICNFOUMwNjJcbn1cblxuLmFjZS10d2lsaWdodCAuYWNlX2NvbW1lbnQge1xuICBmb250LXN0eWxlOiBpdGFsaWM7XG4gIGNvbG9yOiAjNUY1QTYwXG59XG5cbi5hY2UtdHdpbGlnaHQgLmFjZV92YXJpYWJsZSB7XG4gIGNvbG9yOiAjNzU4N0E2XG59XG5cbi5hY2UtdHdpbGlnaHQgLmFjZV94bWwtcGUge1xuICBjb2xvcjogIzQ5NDk0OVxufVxuXG4uYWNlLXR3aWxpZ2h0IC5hY2VfaW5kZW50LWd1aWRlIHtcbiAgYmFja2dyb3VuZDogdXJsKGRhdGE6aW1hZ2UvcG5nO2Jhc2U2NCxpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBQUVBQUFBQ0NBWUFBQUNaZ2JZbkFBQUFFa2xFUVZRSW1XTVFFUkZwWUxDMXRmMFBBQWdPQW5Qbmh4eWlBQUFBQUVsRlRrU3VRbUNDKSByaWdodCByZXBlYXQteVxufVxuXG4uYWNlLXR3aWxpZ2h0IC5hY2VfaW5kZW50LWd1aWRlLWFjdGl2ZSB7XG4gIGJhY2tncm91bmQ6IHVybChkYXRhOmltYWdlL3BuZztiYXNlNjQsaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUFFQUFBQUNDQVlBQUFDWmdiWW5BQUFBRWtsRVFWUUlXMlBRMWRYOXp6Qno1c3ovQUJDY0JGRmVudExsQUFBQUFFbEZUa1N1UW1DQykgcmlnaHQgcmVwZWF0LXk7XG59XG4iOwoKfSk7CgphY2UuZGVmaW5lKCJhY2UvdGhlbWUvdHdpbGlnaHQiLFsicmVxdWlyZSIsImV4cG9ydHMiLCJtb2R1bGUiLCJhY2UvdGhlbWUvdHdpbGlnaHQtY3NzIiwiYWNlL2xpYi9kb20iXSwgZnVuY3Rpb24ocmVxdWlyZSwgZXhwb3J0cywgbW9kdWxlKXtleHBvcnRzLmlzRGFyayA9IHRydWU7CmV4cG9ydHMuY3NzQ2xhc3MgPSAiYWNlLXR3aWxpZ2h0IjsKZXhwb3J0cy5jc3NUZXh0ID0gcmVxdWlyZSgiLi90d2lsaWdodC1jc3MiKTsKdmFyIGRvbSA9IHJlcXVpcmUoIi4uL2xpYi9kb20iKTsKZG9tLmltcG9ydENzc1N0cmluZyhleHBvcnRzLmNzc1RleHQsIGV4cG9ydHMuY3NzQ2xhc3MsIGZhbHNlKTsKCn0pOyAgICAgICAgICAgICAgICAoZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICAgICAgYWNlLnJlcXVpcmUoWyJhY2UvdGhlbWUvdHdpbGlnaHQiXSwgZnVuY3Rpb24obSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1vZHVsZSA9PSAib2JqZWN0IiAmJiB0eXBlb2YgZXhwb3J0cyA9PSAib2JqZWN0IiAmJiBtb2R1bGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gbTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfSkoKTsKICAgICAgICAgICAg"), r.default.config.setModuleUrl("ace/theme/github", "data:text/javascript;base64,YWNlLmRlZmluZSgiYWNlL3RoZW1lL2dpdGh1Yi1jc3MiLFsicmVxdWlyZSIsImV4cG9ydHMiLCJtb2R1bGUiXSwgZnVuY3Rpb24ocmVxdWlyZSwgZXhwb3J0cywgbW9kdWxlKXttb2R1bGUuZXhwb3J0cyA9ICIvKiBDU1Mgc3R5bGUgY29udGVudCBmcm9tIGdpdGh1YidzIGRlZmF1bHQgcHlnbWVudHMgaGlnaGxpZ2h0ZXIgdGVtcGxhdGUuXG4gICBDdXJzb3IgYW5kIHNlbGVjdGlvbiBzdHlsZXMgZnJvbSB0ZXh0bWF0ZS5jc3MuICovXG4uYWNlLWdpdGh1YiAuYWNlX2d1dHRlciB7XG4gIGJhY2tncm91bmQ6ICNlOGU4ZTg7XG4gIGNvbG9yOiAjQUFBO1xufVxuXG4uYWNlLWdpdGh1YiAge1xuICBiYWNrZ3JvdW5kOiAjZmZmO1xuICBjb2xvcjogIzAwMDtcbn1cblxuLmFjZS1naXRodWIgLmFjZV9rZXl3b3JkIHtcbiAgZm9udC13ZWlnaHQ6IGJvbGQ7XG59XG5cbi5hY2UtZ2l0aHViIC5hY2Vfc3RyaW5nIHtcbiAgY29sb3I6ICNEMTQ7XG59XG5cbi5hY2UtZ2l0aHViIC5hY2VfdmFyaWFibGUuYWNlX2NsYXNzIHtcbiAgY29sb3I6IHRlYWw7XG59XG5cbi5hY2UtZ2l0aHViIC5hY2VfY29uc3RhbnQuYWNlX251bWVyaWMge1xuICBjb2xvcjogIzA5OTtcbn1cblxuLmFjZS1naXRodWIgLmFjZV9jb25zdGFudC5hY2VfYnVpbGRpbiB7XG4gIGNvbG9yOiAjMDA4NkIzO1xufVxuXG4uYWNlLWdpdGh1YiAuYWNlX3N1cHBvcnQuYWNlX2Z1bmN0aW9uIHtcbiAgY29sb3I6ICMwMDg2QjM7XG59XG5cbi5hY2UtZ2l0aHViIC5hY2VfY29tbWVudCB7XG4gIGNvbG9yOiAjOTk4O1xuICBmb250LXN0eWxlOiBpdGFsaWM7XG59XG5cbi5hY2UtZ2l0aHViIC5hY2VfdmFyaWFibGUuYWNlX2xhbmd1YWdlICB7XG4gIGNvbG9yOiAjMDA4NkIzO1xufVxuXG4uYWNlLWdpdGh1YiAuYWNlX3BhcmVuIHtcbiAgZm9udC13ZWlnaHQ6IGJvbGQ7XG59XG5cbi5hY2UtZ2l0aHViIC5hY2VfYm9vbGVhbiB7XG4gIGZvbnQtd2VpZ2h0OiBib2xkO1xufVxuXG4uYWNlLWdpdGh1YiAuYWNlX3N0cmluZy5hY2VfcmVnZXhwIHtcbiAgY29sb3I6ICMwMDk5MjY7XG4gIGZvbnQtd2VpZ2h0OiBub3JtYWw7XG59XG5cbi5hY2UtZ2l0aHViIC5hY2VfdmFyaWFibGUuYWNlX2luc3RhbmNlIHtcbiAgY29sb3I6IHRlYWw7XG59XG5cbi5hY2UtZ2l0aHViIC5hY2VfY29uc3RhbnQuYWNlX2xhbmd1YWdlIHtcbiAgZm9udC13ZWlnaHQ6IGJvbGQ7XG59XG5cbi5hY2UtZ2l0aHViIC5hY2VfY3Vyc29yIHtcbiAgY29sb3I6IGJsYWNrO1xufVxuXG4uYWNlLWdpdGh1Yi5hY2VfZm9jdXMgLmFjZV9tYXJrZXItbGF5ZXIgLmFjZV9hY3RpdmUtbGluZSB7XG4gIGJhY2tncm91bmQ6IHJnYigyNTUsIDI1NSwgMjA0KTtcbn1cbi5hY2UtZ2l0aHViIC5hY2VfbWFya2VyLWxheWVyIC5hY2VfYWN0aXZlLWxpbmUge1xuICBiYWNrZ3JvdW5kOiByZ2IoMjQ1LCAyNDUsIDI0NSk7XG59XG5cbi5hY2UtZ2l0aHViIC5hY2VfbWFya2VyLWxheWVyIC5hY2Vfc2VsZWN0aW9uIHtcbiAgYmFja2dyb3VuZDogcmdiKDE4MSwgMjEzLCAyNTUpO1xufVxuXG4uYWNlLWdpdGh1Yi5hY2VfbXVsdGlzZWxlY3QgLmFjZV9zZWxlY3Rpb24uYWNlX3N0YXJ0IHtcbiAgYm94LXNoYWRvdzogMCAwIDNweCAwcHggd2hpdGU7XG59XG4vKiBib2xkIGtleXdvcmRzIGNhdXNlIGN1cnNvciBpc3N1ZXMgZm9yIHNvbWUgZm9udHMgKi9cbi8qIHRoaXMgZGlzYWJsZXMgYm9sZCBzdHlsZSBmb3IgZWRpdG9yIGFuZCBrZWVwcyBmb3Igc3RhdGljIGhpZ2hsaWdodGVyICovXG4uYWNlLWdpdGh1Yi5hY2Vfbm9ib2xkIC5hY2VfbGluZSA+IHNwYW4ge1xuICAgIGZvbnQtd2VpZ2h0OiBub3JtYWwgIWltcG9ydGFudDtcbn1cblxuLmFjZS1naXRodWIgLmFjZV9tYXJrZXItbGF5ZXIgLmFjZV9zdGVwIHtcbiAgYmFja2dyb3VuZDogcmdiKDI1MiwgMjU1LCAwKTtcbn1cblxuLmFjZS1naXRodWIgLmFjZV9tYXJrZXItbGF5ZXIgLmFjZV9zdGFjayB7XG4gIGJhY2tncm91bmQ6IHJnYigxNjQsIDIyOSwgMTAxKTtcbn1cblxuLmFjZS1naXRodWIgLmFjZV9tYXJrZXItbGF5ZXIgLmFjZV9icmFja2V0IHtcbiAgbWFyZ2luOiAtMXB4IDAgMCAtMXB4O1xuICBib3JkZXI6IDFweCBzb2xpZCByZ2IoMTkyLCAxOTIsIDE5Mik7XG59XG5cbi5hY2UtZ2l0aHViIC5hY2VfZ3V0dGVyLWFjdGl2ZS1saW5lIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yIDogcmdiYSgwLCAwLCAwLCAwLjA3KTtcbn1cblxuLmFjZS1naXRodWIgLmFjZV9tYXJrZXItbGF5ZXIgLmFjZV9zZWxlY3RlZC13b3JkIHtcbiAgYmFja2dyb3VuZDogcmdiKDI1MCwgMjUwLCAyNTUpO1xuICBib3JkZXI6IDFweCBzb2xpZCByZ2IoMjAwLCAyMDAsIDI1MCk7XG59XG5cbi5hY2UtZ2l0aHViIC5hY2VfaW52aXNpYmxlIHtcbiAgY29sb3I6ICNCRkJGQkZcbn1cblxuLmFjZS1naXRodWIgLmFjZV9wcmludC1tYXJnaW4ge1xuICB3aWR0aDogMXB4O1xuICBiYWNrZ3JvdW5kOiAjZThlOGU4O1xufVxuXG4uYWNlLWdpdGh1YiAuYWNlX2luZGVudC1ndWlkZSB7XG4gIGJhY2tncm91bmQ6IHVybChcImRhdGE6aW1hZ2UvcG5nO2Jhc2U2NCxpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBQUVBQUFBQ0NBWUFBQUNaZ2JZbkFBQUFFMGxFUVZRSW1XUDQvLy8vZjRiTGx5Ly9Cd0FtVmdkMS93MTEvZ0FBQUFCSlJVNUVya0pnZ2c9PVwiKSByaWdodCByZXBlYXQteTtcbn1cblxuLmFjZS1naXRodWIgLmFjZV9pbmRlbnQtZ3VpZGUtYWN0aXZlIHtcbiAgYmFja2dyb3VuZDogdXJsKFwiZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFBRUFBQUFDQ0FZQUFBQ1pnYlluQUFBQUNYQklXWE1BQUFzVEFBQUxFd0VBbXB3WUFBQUFJR05JVWswQUFIb2xBQUNBZ3dBQStmOEFBSURwQUFCMU1BQUE2bUFBQURxWUFBQVhiNUpmeFVZQUFBQVpTVVJCVkhqYVl2ai8vLzkvaGl2S3l2OEJBQUFBLy84REFDTHFCaGJ2aysvZUFBQUFBRWxGVGtTdVFtQ0NcIikgcmlnaHQgcmVwZWF0LXk7XG59XG4iOwoKfSk7CgphY2UuZGVmaW5lKCJhY2UvdGhlbWUvZ2l0aHViIixbInJlcXVpcmUiLCJleHBvcnRzIiwibW9kdWxlIiwiYWNlL3RoZW1lL2dpdGh1Yi1jc3MiLCJhY2UvbGliL2RvbSJdLCBmdW5jdGlvbihyZXF1aXJlLCBleHBvcnRzLCBtb2R1bGUpe2V4cG9ydHMuaXNEYXJrID0gZmFsc2U7CmV4cG9ydHMuY3NzQ2xhc3MgPSAiYWNlLWdpdGh1YiI7CmV4cG9ydHMuY3NzVGV4dCA9IHJlcXVpcmUoIi4vZ2l0aHViLWNzcyIpOwp2YXIgZG9tID0gcmVxdWlyZSgiLi4vbGliL2RvbSIpOwpkb20uaW1wb3J0Q3NzU3RyaW5nKGV4cG9ydHMuY3NzVGV4dCwgZXhwb3J0cy5jc3NDbGFzcywgZmFsc2UpOwoKfSk7ICAgICAgICAgICAgICAgIChmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICBhY2UucmVxdWlyZShbImFjZS90aGVtZS9naXRodWIiXSwgZnVuY3Rpb24obSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1vZHVsZSA9PSAib2JqZWN0IiAmJiB0eXBlb2YgZXhwb3J0cyA9PSAib2JqZWN0IiAmJiBtb2R1bGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gbTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfSkoKTsKICAgICAgICAgICAg"), r.default.config.setModuleUrl("ace/mode/base", "data:text/javascript;base64,Im5vIHVzZSBzdHJpY3QiOwohKGZ1bmN0aW9uKHdpbmRvdykgewppZiAodHlwZW9mIHdpbmRvdy53aW5kb3cgIT0gInVuZGVmaW5lZCIgJiYgd2luZG93LmRvY3VtZW50KQogICAgcmV0dXJuOwppZiAod2luZG93LnJlcXVpcmUgJiYgd2luZG93LmRlZmluZSkKICAgIHJldHVybjsKCmlmICghd2luZG93LmNvbnNvbGUpIHsKICAgIHdpbmRvdy5jb25zb2xlID0gZnVuY3Rpb24oKSB7CiAgICAgICAgdmFyIG1zZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApOwogICAgICAgIHBvc3RNZXNzYWdlKHt0eXBlOiAibG9nIiwgZGF0YTogbXNnc30pOwogICAgfTsKICAgIHdpbmRvdy5jb25zb2xlLmVycm9yID0KICAgIHdpbmRvdy5jb25zb2xlLndhcm4gPSAKICAgIHdpbmRvdy5jb25zb2xlLmxvZyA9CiAgICB3aW5kb3cuY29uc29sZS50cmFjZSA9IHdpbmRvdy5jb25zb2xlOwp9CndpbmRvdy53aW5kb3cgPSB3aW5kb3c7CndpbmRvdy5hY2UgPSB3aW5kb3c7Cgp3aW5kb3cub25lcnJvciA9IGZ1bmN0aW9uKG1lc3NhZ2UsIGZpbGUsIGxpbmUsIGNvbCwgZXJyKSB7CiAgICBwb3N0TWVzc2FnZSh7dHlwZTogImVycm9yIiwgZGF0YTogewogICAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsCiAgICAgICAgZGF0YTogZXJyICYmIGVyci5kYXRhLAogICAgICAgIGZpbGU6IGZpbGUsCiAgICAgICAgbGluZTogbGluZSwgCiAgICAgICAgY29sOiBjb2wsCiAgICAgICAgc3RhY2s6IGVyciAmJiBlcnIuc3RhY2sKICAgIH19KTsKfTsKCndpbmRvdy5ub3JtYWxpemVNb2R1bGUgPSBmdW5jdGlvbihwYXJlbnRJZCwgbW9kdWxlTmFtZSkgewogICAgLy8gbm9ybWFsaXplIHBsdWdpbiByZXF1aXJlcwogICAgaWYgKG1vZHVsZU5hbWUuaW5kZXhPZigiISIpICE9PSAtMSkgewogICAgICAgIHZhciBjaHVua3MgPSBtb2R1bGVOYW1lLnNwbGl0KCIhIik7CiAgICAgICAgcmV0dXJuIHdpbmRvdy5ub3JtYWxpemVNb2R1bGUocGFyZW50SWQsIGNodW5rc1swXSkgKyAiISIgKyB3aW5kb3cubm9ybWFsaXplTW9kdWxlKHBhcmVudElkLCBjaHVua3NbMV0pOwogICAgfQogICAgLy8gbm9ybWFsaXplIHJlbGF0aXZlIHJlcXVpcmVzCiAgICBpZiAobW9kdWxlTmFtZS5jaGFyQXQoMCkgPT0gIi4iKSB7CiAgICAgICAgdmFyIGJhc2UgPSBwYXJlbnRJZC5zcGxpdCgiLyIpLnNsaWNlKDAsIC0xKS5qb2luKCIvIik7CiAgICAgICAgbW9kdWxlTmFtZSA9IChiYXNlID8gYmFzZSArICIvIiA6ICIiKSArIG1vZHVsZU5hbWU7CiAgICAgICAgCiAgICAgICAgd2hpbGUgKG1vZHVsZU5hbWUuaW5kZXhPZigiLiIpICE9PSAtMSAmJiBwcmV2aW91cyAhPSBtb2R1bGVOYW1lKSB7CiAgICAgICAgICAgIHZhciBwcmV2aW91cyA9IG1vZHVsZU5hbWU7CiAgICAgICAgICAgIG1vZHVsZU5hbWUgPSBtb2R1bGVOYW1lLnJlcGxhY2UoL15cLlwvLywgIiIpLnJlcGxhY2UoL1wvXC5cLy8sICIvIikucmVwbGFjZSgvW15cL10rXC9cLlwuXC8vLCAiIik7CiAgICAgICAgfQogICAgfQogICAgCiAgICByZXR1cm4gbW9kdWxlTmFtZTsKfTsKCndpbmRvdy5yZXF1aXJlID0gZnVuY3Rpb24gcmVxdWlyZShwYXJlbnRJZCwgaWQpIHsKICAgIGlmICghaWQpIHsKICAgICAgICBpZCA9IHBhcmVudElkOwogICAgICAgIHBhcmVudElkID0gbnVsbDsKICAgIH0KICAgIGlmICghaWQuY2hhckF0KQogICAgICAgIHRocm93IG5ldyBFcnJvcigid29ya2VyLmpzIHJlcXVpcmUoKSBhY2NlcHRzIG9ubHkgKHBhcmVudElkLCBpZCkgYXMgYXJndW1lbnRzIik7CgogICAgaWQgPSB3aW5kb3cubm9ybWFsaXplTW9kdWxlKHBhcmVudElkLCBpZCk7CgogICAgdmFyIG1vZHVsZSA9IHdpbmRvdy5yZXF1aXJlLm1vZHVsZXNbaWRdOwogICAgaWYgKG1vZHVsZSkgewogICAgICAgIGlmICghbW9kdWxlLmluaXRpYWxpemVkKSB7CiAgICAgICAgICAgIG1vZHVsZS5pbml0aWFsaXplZCA9IHRydWU7CiAgICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gbW9kdWxlLmZhY3RvcnkoKS5leHBvcnRzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbW9kdWxlLmV4cG9ydHM7CiAgICB9CiAgIAogICAgaWYgKCF3aW5kb3cucmVxdWlyZS50bG5zKQogICAgICAgIHJldHVybiBjb25zb2xlLmxvZygidW5hYmxlIHRvIGxvYWQgIiArIGlkKTsKICAgIAogICAgdmFyIHBhdGggPSByZXNvbHZlTW9kdWxlSWQoaWQsIHdpbmRvdy5yZXF1aXJlLnRsbnMpOwogICAgaWYgKHBhdGguc2xpY2UoLTMpICE9ICIuanMiKSBwYXRoICs9ICIuanMiOwogICAgCiAgICB3aW5kb3cucmVxdWlyZS5pZCA9IGlkOwogICAgd2luZG93LnJlcXVpcmUubW9kdWxlc1tpZF0gPSB7fTsgLy8gcHJldmVudCBpbmZpbml0ZSBsb29wIG9uIGJyb2tlbiBtb2R1bGVzCiAgICBpbXBvcnRTY3JpcHRzKHBhdGgpOwogICAgcmV0dXJuIHdpbmRvdy5yZXF1aXJlKHBhcmVudElkLCBpZCk7Cn07CmZ1bmN0aW9uIHJlc29sdmVNb2R1bGVJZChpZCwgcGF0aHMpIHsKICAgIHZhciB0ZXN0UGF0aCA9IGlkLCB0YWlsID0gIiI7CiAgICB3aGlsZSAodGVzdFBhdGgpIHsKICAgICAgICB2YXIgYWxpYXMgPSBwYXRoc1t0ZXN0UGF0aF07CiAgICAgICAgaWYgKHR5cGVvZiBhbGlhcyA9PSAic3RyaW5nIikgewogICAgICAgICAgICByZXR1cm4gYWxpYXMgKyB0YWlsOwogICAgICAgIH0gZWxzZSBpZiAoYWxpYXMpIHsKICAgICAgICAgICAgcmV0dXJuICBhbGlhcy5sb2NhdGlvbi5yZXBsYWNlKC9cLyokLywgIi8iKSArICh0YWlsIHx8IGFsaWFzLm1haW4gfHwgYWxpYXMubmFtZSk7CiAgICAgICAgfSBlbHNlIGlmIChhbGlhcyA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgcmV0dXJuICIiOwogICAgICAgIH0KICAgICAgICB2YXIgaSA9IHRlc3RQYXRoLmxhc3RJbmRleE9mKCIvIik7CiAgICAgICAgaWYgKGkgPT09IC0xKSBicmVhazsKICAgICAgICB0YWlsID0gdGVzdFBhdGguc3Vic3RyKGkpICsgdGFpbDsKICAgICAgICB0ZXN0UGF0aCA9IHRlc3RQYXRoLnNsaWNlKDAsIGkpOwogICAgfQogICAgcmV0dXJuIGlkOwp9CndpbmRvdy5yZXF1aXJlLm1vZHVsZXMgPSB7fTsKd2luZG93LnJlcXVpcmUudGxucyA9IHt9OwoKd2luZG93LmRlZmluZSA9IGZ1bmN0aW9uKGlkLCBkZXBzLCBmYWN0b3J5KSB7CiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PSAyKSB7CiAgICAgICAgZmFjdG9yeSA9IGRlcHM7CiAgICAgICAgaWYgKHR5cGVvZiBpZCAhPSAic3RyaW5nIikgewogICAgICAgICAgICBkZXBzID0gaWQ7CiAgICAgICAgICAgIGlkID0gd2luZG93LnJlcXVpcmUuaWQ7CiAgICAgICAgfQogICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID09IDEpIHsKICAgICAgICBmYWN0b3J5ID0gaWQ7CiAgICAgICAgZGVwcyA9IFtdOwogICAgICAgIGlkID0gd2luZG93LnJlcXVpcmUuaWQ7CiAgICB9CiAgICAKICAgIGlmICh0eXBlb2YgZmFjdG9yeSAhPSAiZnVuY3Rpb24iKSB7CiAgICAgICAgd2luZG93LnJlcXVpcmUubW9kdWxlc1tpZF0gPSB7CiAgICAgICAgICAgIGV4cG9ydHM6IGZhY3RvcnksCiAgICAgICAgICAgIGluaXRpYWxpemVkOiB0cnVlCiAgICAgICAgfTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKCFkZXBzLmxlbmd0aCkKICAgICAgICAvLyBJZiB0aGVyZSBpcyBubyBkZXBlbmRlbmNpZXMsIHdlIGluamVjdCAicmVxdWlyZSIsICJleHBvcnRzIiBhbmQKICAgICAgICAvLyAibW9kdWxlIiBhcyBkZXBlbmRlbmNpZXMsIHRvIHByb3ZpZGUgQ29tbW9uSlMgY29tcGF0aWJpbGl0eS4KICAgICAgICBkZXBzID0gWyJyZXF1aXJlIiwgImV4cG9ydHMiLCAibW9kdWxlIl07CgogICAgdmFyIHJlcSA9IGZ1bmN0aW9uKGNoaWxkSWQpIHsKICAgICAgICByZXR1cm4gd2luZG93LnJlcXVpcmUoaWQsIGNoaWxkSWQpOwogICAgfTsKCiAgICB3aW5kb3cucmVxdWlyZS5tb2R1bGVzW2lkXSA9IHsKICAgICAgICBleHBvcnRzOiB7fSwKICAgICAgICBmYWN0b3J5OiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIG1vZHVsZSA9IHRoaXM7CiAgICAgICAgICAgIHZhciByZXR1cm5FeHBvcnRzID0gZmFjdG9yeS5hcHBseSh0aGlzLCBkZXBzLnNsaWNlKDAsIGZhY3RvcnkubGVuZ3RoKS5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKGRlcCkgewogICAgICAgICAgICAgICAgICAgIC8vIEJlY2F1c2UgInJlcXVpcmUiLCAiZXhwb3J0cyIgYW5kICJtb2R1bGUiIGFyZW4ndCBhY3R1YWwKICAgICAgICAgICAgICAgICAgICAvLyBkZXBlbmRlbmNpZXMsIHdlIG11c3QgaGFuZGxlIHRoZW0gc2VwZXJhdGVseS4KICAgICAgICAgICAgICAgICAgICBjYXNlICJyZXF1aXJlIjogcmV0dXJuIHJlcTsKICAgICAgICAgICAgICAgICAgICBjYXNlICJleHBvcnRzIjogcmV0dXJuIG1vZHVsZS5leHBvcnRzOwogICAgICAgICAgICAgICAgICAgIGNhc2UgIm1vZHVsZSI6ICByZXR1cm4gbW9kdWxlOwogICAgICAgICAgICAgICAgICAgIC8vIEJ1dCBmb3IgYWxsIG90aGVyIGRlcGVuZGVuY2llcywgd2UgY2FuIGp1c3QgZ28gYWhlYWQgYW5kCiAgICAgICAgICAgICAgICAgICAgLy8gcmVxdWlyZSB0aGVtLgogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6ICAgICAgICByZXR1cm4gcmVxKGRlcCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pKTsKICAgICAgICAgICAgaWYgKHJldHVybkV4cG9ydHMpCiAgICAgICAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IHJldHVybkV4cG9ydHM7CiAgICAgICAgICAgIHJldHVybiBtb2R1bGU7CiAgICAgICAgfQogICAgfTsKfTsKd2luZG93LmRlZmluZS5hbWQgPSB7fTsKd2luZG93LnJlcXVpcmUudGxucyA9IHt9Owp3aW5kb3cuaW5pdEJhc2VVcmxzICA9IGZ1bmN0aW9uIGluaXRCYXNlVXJscyh0b3BMZXZlbE5hbWVzcGFjZXMpIHsKICAgIGZvciAodmFyIGkgaW4gdG9wTGV2ZWxOYW1lc3BhY2VzKQogICAgICAgIHRoaXMucmVxdWlyZS50bG5zW2ldID0gdG9wTGV2ZWxOYW1lc3BhY2VzW2ldOwp9OwoKd2luZG93LmluaXRTZW5kZXIgPSBmdW5jdGlvbiBpbml0U2VuZGVyKCkgewoKICAgIHZhciBFdmVudEVtaXR0ZXIgPSB3aW5kb3cucmVxdWlyZSgiYWNlL2xpYi9ldmVudF9lbWl0dGVyIikuRXZlbnRFbWl0dGVyOwogICAgdmFyIG9vcCA9IHdpbmRvdy5yZXF1aXJlKCJhY2UvbGliL29vcCIpOwogICAgCiAgICB2YXIgU2VuZGVyID0gZnVuY3Rpb24oKSB7fTsKICAgIAogICAgKGZ1bmN0aW9uKCkgewogICAgICAgIAogICAgICAgIG9vcC5pbXBsZW1lbnQodGhpcywgRXZlbnRFbWl0dGVyKTsKICAgICAgICAgICAgICAgIAogICAgICAgIHRoaXMuY2FsbGJhY2sgPSBmdW5jdGlvbihkYXRhLCBjYWxsYmFja0lkKSB7CiAgICAgICAgICAgIHBvc3RNZXNzYWdlKHsKICAgICAgICAgICAgICAgIHR5cGU6ICJjYWxsIiwKICAgICAgICAgICAgICAgIGlkOiBjYWxsYmFja0lkLAogICAgICAgICAgICAgICAgZGF0YTogZGF0YQogICAgICAgICAgICB9KTsKICAgICAgICB9OwogICAgCiAgICAgICAgdGhpcy5lbWl0ID0gZnVuY3Rpb24obmFtZSwgZGF0YSkgewogICAgICAgICAgICBwb3N0TWVzc2FnZSh7CiAgICAgICAgICAgICAgICB0eXBlOiAiZXZlbnQiLAogICAgICAgICAgICAgICAgbmFtZTogbmFtZSwKICAgICAgICAgICAgICAgIGRhdGE6IGRhdGEKICAgICAgICAgICAgfSk7CiAgICAgICAgfTsKICAgICAgICAKICAgIH0pLmNhbGwoU2VuZGVyLnByb3RvdHlwZSk7CiAgICAKICAgIHJldHVybiBuZXcgU2VuZGVyKCk7Cn07Cgp2YXIgbWFpbiA9IHdpbmRvdy5tYWluID0gbnVsbDsKdmFyIHNlbmRlciA9IHdpbmRvdy5zZW5kZXIgPSBudWxsOwoKd2luZG93Lm9ubWVzc2FnZSA9IGZ1bmN0aW9uKGUpIHsKICAgIHZhciBtc2cgPSBlLmRhdGE7CiAgICBpZiAobXNnLmV2ZW50ICYmIHNlbmRlcikgewogICAgICAgIHNlbmRlci5fc2lnbmFsKG1zZy5ldmVudCwgbXNnLmRhdGEpOwogICAgfQogICAgZWxzZSBpZiAobXNnLmNvbW1hbmQpIHsKICAgICAgICBpZiAobWFpblttc2cuY29tbWFuZF0pCiAgICAgICAgICAgIG1haW5bbXNnLmNvbW1hbmRdLmFwcGx5KG1haW4sIG1zZy5hcmdzKTsKICAgICAgICBlbHNlIGlmICh3aW5kb3dbbXNnLmNvbW1hbmRdKQogICAgICAgICAgICB3aW5kb3dbbXNnLmNvbW1hbmRdLmFwcGx5KHdpbmRvdywgbXNnLmFyZ3MpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJVbmtub3duIGNvbW1hbmQ6IiArIG1zZy5jb21tYW5kKTsKICAgIH0KICAgIGVsc2UgaWYgKG1zZy5pbml0KSB7CiAgICAgICAgd2luZG93LmluaXRCYXNlVXJscyhtc2cudGxucyk7CiAgICAgICAgc2VuZGVyID0gd2luZG93LnNlbmRlciA9IHdpbmRvdy5pbml0U2VuZGVyKCk7CiAgICAgICAgdmFyIGNsYXp6ID0gdGhpcy5yZXF1aXJlKG1zZy5tb2R1bGUpW21zZy5jbGFzc25hbWVdOwogICAgICAgIG1haW4gPSB3aW5kb3cubWFpbiA9IG5ldyBjbGF6eihzZW5kZXIpOwogICAgfQp9Owp9KSh0aGlzKTsKCmFjZS5kZWZpbmUoImFjZS9saWIvb29wIixbXSwgZnVuY3Rpb24ocmVxdWlyZSwgZXhwb3J0cywgbW9kdWxlKXsidXNlIHN0cmljdCI7CmV4cG9ydHMuaW5oZXJpdHMgPSBmdW5jdGlvbiAoY3Rvciwgc3VwZXJDdG9yKSB7CiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvcjsKICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7CiAgICAgICAgY29uc3RydWN0b3I6IHsKICAgICAgICAgICAgdmFsdWU6IGN0b3IsCiAgICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLAogICAgICAgICAgICB3cml0YWJsZTogdHJ1ZSwKICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlCiAgICAgICAgfQogICAgfSk7Cn07CmV4cG9ydHMubWl4aW4gPSBmdW5jdGlvbiAob2JqLCBtaXhpbikgewogICAgZm9yICh2YXIga2V5IGluIG1peGluKSB7CiAgICAgICAgb2JqW2tleV0gPSBtaXhpbltrZXldOwogICAgfQogICAgcmV0dXJuIG9iajsKfTsKZXhwb3J0cy5pbXBsZW1lbnQgPSBmdW5jdGlvbiAocHJvdG8sIG1peGluKSB7CiAgICBleHBvcnRzLm1peGluKHByb3RvLCBtaXhpbik7Cn07Cgp9KTsKCmFjZS5kZWZpbmUoImFjZS9hcHBseV9kZWx0YSIsW10sIGZ1bmN0aW9uKHJlcXVpcmUsIGV4cG9ydHMsIG1vZHVsZSl7InVzZSBzdHJpY3QiOwpmdW5jdGlvbiB0aHJvd0RlbHRhRXJyb3IoZGVsdGEsIGVycm9yVGV4dCkgewogICAgY29uc29sZS5sb2coIkludmFsaWQgRGVsdGE6IiwgZGVsdGEpOwogICAgdGhyb3cgIkludmFsaWQgRGVsdGE6ICIgKyBlcnJvclRleHQ7Cn0KZnVuY3Rpb24gcG9zaXRpb25JbkRvY3VtZW50KGRvY0xpbmVzLCBwb3NpdGlvbikgewogICAgcmV0dXJuIHBvc2l0aW9uLnJvdyA+PSAwICYmIHBvc2l0aW9uLnJvdyA8IGRvY0xpbmVzLmxlbmd0aCAmJgogICAgICAgIHBvc2l0aW9uLmNvbHVtbiA+PSAwICYmIHBvc2l0aW9uLmNvbHVtbiA8PSBkb2NMaW5lc1twb3NpdGlvbi5yb3ddLmxlbmd0aDsKfQpmdW5jdGlvbiB2YWxpZGF0ZURlbHRhKGRvY0xpbmVzLCBkZWx0YSkgewogICAgaWYgKGRlbHRhLmFjdGlvbiAhPSAiaW5zZXJ0IiAmJiBkZWx0YS5hY3Rpb24gIT0gInJlbW92ZSIpCiAgICAgICAgdGhyb3dEZWx0YUVycm9yKGRlbHRhLCAiZGVsdGEuYWN0aW9uIG11c3QgYmUgJ2luc2VydCcgb3IgJ3JlbW92ZSciKTsKICAgIGlmICghKGRlbHRhLmxpbmVzIGluc3RhbmNlb2YgQXJyYXkpKQogICAgICAgIHRocm93RGVsdGFFcnJvcihkZWx0YSwgImRlbHRhLmxpbmVzIG11c3QgYmUgYW4gQXJyYXkiKTsKICAgIGlmICghZGVsdGEuc3RhcnQgfHwgIWRlbHRhLmVuZCkKICAgICAgICB0aHJvd0RlbHRhRXJyb3IoZGVsdGEsICJkZWx0YS5zdGFydC9lbmQgbXVzdCBiZSBhbiBwcmVzZW50Iik7CiAgICB2YXIgc3RhcnQgPSBkZWx0YS5zdGFydDsKICAgIGlmICghcG9zaXRpb25JbkRvY3VtZW50KGRvY0xpbmVzLCBkZWx0YS5zdGFydCkpCiAgICAgICAgdGhyb3dEZWx0YUVycm9yKGRlbHRhLCAiZGVsdGEuc3RhcnQgbXVzdCBiZSBjb250YWluZWQgaW4gZG9jdW1lbnQiKTsKICAgIHZhciBlbmQgPSBkZWx0YS5lbmQ7CiAgICBpZiAoZGVsdGEuYWN0aW9uID09ICJyZW1vdmUiICYmICFwb3NpdGlvbkluRG9jdW1lbnQoZG9jTGluZXMsIGVuZCkpCiAgICAgICAgdGhyb3dEZWx0YUVycm9yKGRlbHRhLCAiZGVsdGEuZW5kIG11c3QgY29udGFpbmVkIGluIGRvY3VtZW50IGZvciAncmVtb3ZlJyBhY3Rpb25zIik7CiAgICB2YXIgbnVtUmFuZ2VSb3dzID0gZW5kLnJvdyAtIHN0YXJ0LnJvdzsKICAgIHZhciBudW1SYW5nZUxhc3RMaW5lQ2hhcnMgPSAoZW5kLmNvbHVtbiAtIChudW1SYW5nZVJvd3MgPT0gMCA/IHN0YXJ0LmNvbHVtbiA6IDApKTsKICAgIGlmIChudW1SYW5nZVJvd3MgIT0gZGVsdGEubGluZXMubGVuZ3RoIC0gMSB8fCBkZWx0YS5saW5lc1tudW1SYW5nZVJvd3NdLmxlbmd0aCAhPSBudW1SYW5nZUxhc3RMaW5lQ2hhcnMpCiAgICAgICAgdGhyb3dEZWx0YUVycm9yKGRlbHRhLCAiZGVsdGEucmFuZ2UgbXVzdCBtYXRjaCBkZWx0YSBsaW5lcyIpOwp9CmV4cG9ydHMuYXBwbHlEZWx0YSA9IGZ1bmN0aW9uIChkb2NMaW5lcywgZGVsdGEsIGRvTm90VmFsaWRhdGUpIHsKICAgIHZhciByb3cgPSBkZWx0YS5zdGFydC5yb3c7CiAgICB2YXIgc3RhcnRDb2x1bW4gPSBkZWx0YS5zdGFydC5jb2x1bW47CiAgICB2YXIgbGluZSA9IGRvY0xpbmVzW3Jvd10gfHwgIiI7CiAgICBzd2l0Y2ggKGRlbHRhLmFjdGlvbikgewogICAgICAgIGNhc2UgImluc2VydCI6CiAgICAgICAgICAgIHZhciBsaW5lcyA9IGRlbHRhLmxpbmVzOwogICAgICAgICAgICBpZiAobGluZXMubGVuZ3RoID09PSAxKSB7CiAgICAgICAgICAgICAgICBkb2NMaW5lc1tyb3ddID0gbGluZS5zdWJzdHJpbmcoMCwgc3RhcnRDb2x1bW4pICsgZGVsdGEubGluZXNbMF0gKyBsaW5lLnN1YnN0cmluZyhzdGFydENvbHVtbik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICB2YXIgYXJncyA9IFtyb3csIDFdLmNvbmNhdChkZWx0YS5saW5lcyk7CiAgICAgICAgICAgICAgICBkb2NMaW5lcy5zcGxpY2UuYXBwbHkoZG9jTGluZXMsIGFyZ3MpOwogICAgICAgICAgICAgICAgZG9jTGluZXNbcm93XSA9IGxpbmUuc3Vic3RyaW5nKDAsIHN0YXJ0Q29sdW1uKSArIGRvY0xpbmVzW3Jvd107CiAgICAgICAgICAgICAgICBkb2NMaW5lc1tyb3cgKyBkZWx0YS5saW5lcy5sZW5ndGggLSAxXSArPSBsaW5lLnN1YnN0cmluZyhzdGFydENvbHVtbik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAicmVtb3ZlIjoKICAgICAgICAgICAgdmFyIGVuZENvbHVtbiA9IGRlbHRhLmVuZC5jb2x1bW47CiAgICAgICAgICAgIHZhciBlbmRSb3cgPSBkZWx0YS5lbmQucm93OwogICAgICAgICAgICBpZiAocm93ID09PSBlbmRSb3cpIHsKICAgICAgICAgICAgICAgIGRvY0xpbmVzW3Jvd10gPSBsaW5lLnN1YnN0cmluZygwLCBzdGFydENvbHVtbikgKyBsaW5lLnN1YnN0cmluZyhlbmRDb2x1bW4pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgZG9jTGluZXMuc3BsaWNlKHJvdywgZW5kUm93IC0gcm93ICsgMSwgbGluZS5zdWJzdHJpbmcoMCwgc3RhcnRDb2x1bW4pICsgZG9jTGluZXNbZW5kUm93XS5zdWJzdHJpbmcoZW5kQ29sdW1uKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICB9Cn07Cgp9KTsKCmFjZS5kZWZpbmUoImFjZS9saWIvZXZlbnRfZW1pdHRlciIsW10sIGZ1bmN0aW9uKHJlcXVpcmUsIGV4cG9ydHMsIG1vZHVsZSl7InVzZSBzdHJpY3QiOwp2YXIgRXZlbnRFbWl0dGVyID0ge307CnZhciBzdG9wUHJvcGFnYXRpb24gPSBmdW5jdGlvbiAoKSB7IHRoaXMucHJvcGFnYXRpb25TdG9wcGVkID0gdHJ1ZTsgfTsKdmFyIHByZXZlbnREZWZhdWx0ID0gZnVuY3Rpb24gKCkgeyB0aGlzLmRlZmF1bHRQcmV2ZW50ZWQgPSB0cnVlOyB9OwpFdmVudEVtaXR0ZXIuX2VtaXQgPQogICAgRXZlbnRFbWl0dGVyLl9kaXNwYXRjaEV2ZW50ID0gZnVuY3Rpb24gKGV2ZW50TmFtZSwgZSkgewogICAgICAgIHRoaXMuX2V2ZW50UmVnaXN0cnkgfHwgKHRoaXMuX2V2ZW50UmVnaXN0cnkgPSB7fSk7CiAgICAgICAgdGhpcy5fZGVmYXVsdEhhbmRsZXJzIHx8ICh0aGlzLl9kZWZhdWx0SGFuZGxlcnMgPSB7fSk7CiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuX2V2ZW50UmVnaXN0cnlbZXZlbnROYW1lXSB8fCBbXTsKICAgICAgICB2YXIgZGVmYXVsdEhhbmRsZXIgPSB0aGlzLl9kZWZhdWx0SGFuZGxlcnNbZXZlbnROYW1lXTsKICAgICAgICBpZiAoIWxpc3RlbmVycy5sZW5ndGggJiYgIWRlZmF1bHRIYW5kbGVyKQogICAgICAgICAgICByZXR1cm47CiAgICAgICAgaWYgKHR5cGVvZiBlICE9ICJvYmplY3QiIHx8ICFlKQogICAgICAgICAgICBlID0ge307CiAgICAgICAgaWYgKCFlLnR5cGUpCiAgICAgICAgICAgIGUudHlwZSA9IGV2ZW50TmFtZTsKICAgICAgICBpZiAoIWUuc3RvcFByb3BhZ2F0aW9uKQogICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbiA9IHN0b3BQcm9wYWdhdGlvbjsKICAgICAgICBpZiAoIWUucHJldmVudERlZmF1bHQpCiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQgPSBwcmV2ZW50RGVmYXVsdDsKICAgICAgICBsaXN0ZW5lcnMgPSBsaXN0ZW5lcnMuc2xpY2UoKTsKICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICBsaXN0ZW5lcnNbaV0oZSwgdGhpcyk7CiAgICAgICAgICAgIGlmIChlLnByb3BhZ2F0aW9uU3RvcHBlZCkKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBpZiAoZGVmYXVsdEhhbmRsZXIgJiYgIWUuZGVmYXVsdFByZXZlbnRlZCkKICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRIYW5kbGVyKGUsIHRoaXMpOwogICAgfTsKRXZlbnRFbWl0dGVyLl9zaWduYWwgPSBmdW5jdGlvbiAoZXZlbnROYW1lLCBlKSB7CiAgICB2YXIgbGlzdGVuZXJzID0gKHRoaXMuX2V2ZW50UmVnaXN0cnkgfHwge30pW2V2ZW50TmFtZV07CiAgICBpZiAoIWxpc3RlbmVycykKICAgICAgICByZXR1cm47CiAgICBsaXN0ZW5lcnMgPSBsaXN0ZW5lcnMuc2xpY2UoKTsKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDsgaSsrKQogICAgICAgIGxpc3RlbmVyc1tpXShlLCB0aGlzKTsKfTsKRXZlbnRFbWl0dGVyLm9uY2UgPSBmdW5jdGlvbiAoZXZlbnROYW1lLCBjYWxsYmFjaykgewogICAgdmFyIF9zZWxmID0gdGhpczsKICAgIHRoaXMub24oZXZlbnROYW1lLCBmdW5jdGlvbiBuZXdDYWxsYmFjaygpIHsKICAgICAgICBfc2VsZi5vZmYoZXZlbnROYW1lLCBuZXdDYWxsYmFjayk7CiAgICAgICAgY2FsbGJhY2suYXBwbHkobnVsbCwgYXJndW1lbnRzKTsKICAgIH0pOwogICAgaWYgKCFjYWxsYmFjaykgewogICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkgewogICAgICAgICAgICBjYWxsYmFjayA9IHJlc29sdmU7CiAgICAgICAgfSk7CiAgICB9Cn07CkV2ZW50RW1pdHRlci5zZXREZWZhdWx0SGFuZGxlciA9IGZ1bmN0aW9uIChldmVudE5hbWUsIGNhbGxiYWNrKSB7CiAgICB2YXIgaGFuZGxlcnMgPSB0aGlzLl9kZWZhdWx0SGFuZGxlcnM7CiAgICBpZiAoIWhhbmRsZXJzKQogICAgICAgIGhhbmRsZXJzID0gdGhpcy5fZGVmYXVsdEhhbmRsZXJzID0geyBfZGlzYWJsZWRfOiB7fSB9OwogICAgaWYgKGhhbmRsZXJzW2V2ZW50TmFtZV0pIHsKICAgICAgICB2YXIgb2xkID0gaGFuZGxlcnNbZXZlbnROYW1lXTsKICAgICAgICB2YXIgZGlzYWJsZWQgPSBoYW5kbGVycy5fZGlzYWJsZWRfW2V2ZW50TmFtZV07CiAgICAgICAgaWYgKCFkaXNhYmxlZCkKICAgICAgICAgICAgaGFuZGxlcnMuX2Rpc2FibGVkX1tldmVudE5hbWVdID0gZGlzYWJsZWQgPSBbXTsKICAgICAgICBkaXNhYmxlZC5wdXNoKG9sZCk7CiAgICAgICAgdmFyIGkgPSBkaXNhYmxlZC5pbmRleE9mKGNhbGxiYWNrKTsKICAgICAgICBpZiAoaSAhPSAtMSkKICAgICAgICAgICAgZGlzYWJsZWQuc3BsaWNlKGksIDEpOwogICAgfQogICAgaGFuZGxlcnNbZXZlbnROYW1lXSA9IGNhbGxiYWNrOwp9OwpFdmVudEVtaXR0ZXIucmVtb3ZlRGVmYXVsdEhhbmRsZXIgPSBmdW5jdGlvbiAoZXZlbnROYW1lLCBjYWxsYmFjaykgewogICAgdmFyIGhhbmRsZXJzID0gdGhpcy5fZGVmYXVsdEhhbmRsZXJzOwogICAgaWYgKCFoYW5kbGVycykKICAgICAgICByZXR1cm47CiAgICB2YXIgZGlzYWJsZWQgPSBoYW5kbGVycy5fZGlzYWJsZWRfW2V2ZW50TmFtZV07CiAgICBpZiAoaGFuZGxlcnNbZXZlbnROYW1lXSA9PSBjYWxsYmFjaykgewogICAgICAgIGlmIChkaXNhYmxlZCkKICAgICAgICAgICAgdGhpcy5zZXREZWZhdWx0SGFuZGxlcihldmVudE5hbWUsIGRpc2FibGVkLnBvcCgpKTsKICAgIH0KICAgIGVsc2UgaWYgKGRpc2FibGVkKSB7CiAgICAgICAgdmFyIGkgPSBkaXNhYmxlZC5pbmRleE9mKGNhbGxiYWNrKTsKICAgICAgICBpZiAoaSAhPSAtMSkKICAgICAgICAgICAgZGlzYWJsZWQuc3BsaWNlKGksIDEpOwogICAgfQp9OwpFdmVudEVtaXR0ZXIub24gPQogICAgRXZlbnRFbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbiAoZXZlbnROYW1lLCBjYWxsYmFjaywgY2FwdHVyaW5nKSB7CiAgICAgICAgdGhpcy5fZXZlbnRSZWdpc3RyeSA9IHRoaXMuX2V2ZW50UmVnaXN0cnkgfHwge307CiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuX2V2ZW50UmVnaXN0cnlbZXZlbnROYW1lXTsKICAgICAgICBpZiAoIWxpc3RlbmVycykKICAgICAgICAgICAgbGlzdGVuZXJzID0gdGhpcy5fZXZlbnRSZWdpc3RyeVtldmVudE5hbWVdID0gW107CiAgICAgICAgaWYgKGxpc3RlbmVycy5pbmRleE9mKGNhbGxiYWNrKSA9PSAtMSkKICAgICAgICAgICAgbGlzdGVuZXJzW2NhcHR1cmluZyA/ICJ1bnNoaWZ0IiA6ICJwdXNoIl0oY2FsbGJhY2spOwogICAgICAgIHJldHVybiBjYWxsYmFjazsKICAgIH07CkV2ZW50RW1pdHRlci5vZmYgPQogICAgRXZlbnRFbWl0dGVyLnJlbW92ZUxpc3RlbmVyID0KICAgICAgICBFdmVudEVtaXR0ZXIucmVtb3ZlRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uIChldmVudE5hbWUsIGNhbGxiYWNrKSB7CiAgICAgICAgICAgIHRoaXMuX2V2ZW50UmVnaXN0cnkgPSB0aGlzLl9ldmVudFJlZ2lzdHJ5IHx8IHt9OwogICAgICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5fZXZlbnRSZWdpc3RyeVtldmVudE5hbWVdOwogICAgICAgICAgICBpZiAoIWxpc3RlbmVycykKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgdmFyIGluZGV4ID0gbGlzdGVuZXJzLmluZGV4T2YoY2FsbGJhY2spOwogICAgICAgICAgICBpZiAoaW5kZXggIT09IC0xKQogICAgICAgICAgICAgICAgbGlzdGVuZXJzLnNwbGljZShpbmRleCwgMSk7CiAgICAgICAgfTsKRXZlbnRFbWl0dGVyLnJlbW92ZUFsbExpc3RlbmVycyA9IGZ1bmN0aW9uIChldmVudE5hbWUpIHsKICAgIGlmICghZXZlbnROYW1lKQogICAgICAgIHRoaXMuX2V2ZW50UmVnaXN0cnkgPSB0aGlzLl9kZWZhdWx0SGFuZGxlcnMgPSB1bmRlZmluZWQ7CiAgICBpZiAodGhpcy5fZXZlbnRSZWdpc3RyeSkKICAgICAgICB0aGlzLl9ldmVudFJlZ2lzdHJ5W2V2ZW50TmFtZV0gPSB1bmRlZmluZWQ7CiAgICBpZiAodGhpcy5fZGVmYXVsdEhhbmRsZXJzKQogICAgICAgIHRoaXMuX2RlZmF1bHRIYW5kbGVyc1tldmVudE5hbWVdID0gdW5kZWZpbmVkOwp9OwpleHBvcnRzLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjsKCn0pOwoKYWNlLmRlZmluZSgiYWNlL3JhbmdlIixbXSwgZnVuY3Rpb24ocmVxdWlyZSwgZXhwb3J0cywgbW9kdWxlKXsidXNlIHN0cmljdCI7CnZhciBSYW5nZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHsKICAgIGZ1bmN0aW9uIFJhbmdlKHN0YXJ0Um93LCBzdGFydENvbHVtbiwgZW5kUm93LCBlbmRDb2x1bW4pIHsKICAgICAgICB0aGlzLnN0YXJ0ID0gewogICAgICAgICAgICByb3c6IHN0YXJ0Um93LAogICAgICAgICAgICBjb2x1bW46IHN0YXJ0Q29sdW1uCiAgICAgICAgfTsKICAgICAgICB0aGlzLmVuZCA9IHsKICAgICAgICAgICAgcm93OiBlbmRSb3csCiAgICAgICAgICAgIGNvbHVtbjogZW5kQ29sdW1uCiAgICAgICAgfTsKICAgIH0KICAgIFJhbmdlLnByb3RvdHlwZS5pc0VxdWFsID0gZnVuY3Rpb24gKHJhbmdlKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuc3RhcnQucm93ID09PSByYW5nZS5zdGFydC5yb3cgJiYKICAgICAgICAgICAgdGhpcy5lbmQucm93ID09PSByYW5nZS5lbmQucm93ICYmCiAgICAgICAgICAgIHRoaXMuc3RhcnQuY29sdW1uID09PSByYW5nZS5zdGFydC5jb2x1bW4gJiYKICAgICAgICAgICAgdGhpcy5lbmQuY29sdW1uID09PSByYW5nZS5lbmQuY29sdW1uOwogICAgfTsKICAgIFJhbmdlLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHsKICAgICAgICByZXR1cm4gKCJSYW5nZTogWyIgKyB0aGlzLnN0YXJ0LnJvdyArICIvIiArIHRoaXMuc3RhcnQuY29sdW1uICsKICAgICAgICAgICAgIl0gLT4gWyIgKyB0aGlzLmVuZC5yb3cgKyAiLyIgKyB0aGlzLmVuZC5jb2x1bW4gKyAiXSIpOwogICAgfTsKICAgIFJhbmdlLnByb3RvdHlwZS5jb250YWlucyA9IGZ1bmN0aW9uIChyb3csIGNvbHVtbikgewogICAgICAgIHJldHVybiB0aGlzLmNvbXBhcmUocm93LCBjb2x1bW4pID09IDA7CiAgICB9OwogICAgUmFuZ2UucHJvdG90eXBlLmNvbXBhcmVSYW5nZSA9IGZ1bmN0aW9uIChyYW5nZSkgewogICAgICAgIHZhciBjbXAsIGVuZCA9IHJhbmdlLmVuZCwgc3RhcnQgPSByYW5nZS5zdGFydDsKICAgICAgICBjbXAgPSB0aGlzLmNvbXBhcmUoZW5kLnJvdywgZW5kLmNvbHVtbik7CiAgICAgICAgaWYgKGNtcCA9PSAxKSB7CiAgICAgICAgICAgIGNtcCA9IHRoaXMuY29tcGFyZShzdGFydC5yb3csIHN0YXJ0LmNvbHVtbik7CiAgICAgICAgICAgIGlmIChjbXAgPT0gMSkgewogICAgICAgICAgICAgICAgcmV0dXJuIDI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoY21wID09IDApIHsKICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoY21wID09IC0xKSB7CiAgICAgICAgICAgIHJldHVybiAtMjsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGNtcCA9IHRoaXMuY29tcGFyZShzdGFydC5yb3csIHN0YXJ0LmNvbHVtbik7CiAgICAgICAgICAgIGlmIChjbXAgPT0gLTEpIHsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChjbXAgPT0gMSkgewogICAgICAgICAgICAgICAgcmV0dXJuIDQyOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9OwogICAgUmFuZ2UucHJvdG90eXBlLmNvbXBhcmVQb2ludCA9IGZ1bmN0aW9uIChwKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuY29tcGFyZShwLnJvdywgcC5jb2x1bW4pOwogICAgfTsKICAgIFJhbmdlLnByb3RvdHlwZS5jb250YWluc1JhbmdlID0gZnVuY3Rpb24gKHJhbmdlKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuY29tcGFyZVBvaW50KHJhbmdlLnN0YXJ0KSA9PSAwICYmIHRoaXMuY29tcGFyZVBvaW50KHJhbmdlLmVuZCkgPT0gMDsKICAgIH07CiAgICBSYW5nZS5wcm90b3R5cGUuaW50ZXJzZWN0cyA9IGZ1bmN0aW9uIChyYW5nZSkgewogICAgICAgIHZhciBjbXAgPSB0aGlzLmNvbXBhcmVSYW5nZShyYW5nZSk7CiAgICAgICAgcmV0dXJuIChjbXAgPT0gLTEgfHwgY21wID09IDAgfHwgY21wID09IDEpOwogICAgfTsKICAgIFJhbmdlLnByb3RvdHlwZS5pc0VuZCA9IGZ1bmN0aW9uIChyb3csIGNvbHVtbikgewogICAgICAgIHJldHVybiB0aGlzLmVuZC5yb3cgPT0gcm93ICYmIHRoaXMuZW5kLmNvbHVtbiA9PSBjb2x1bW47CiAgICB9OwogICAgUmFuZ2UucHJvdG90eXBlLmlzU3RhcnQgPSBmdW5jdGlvbiAocm93LCBjb2x1bW4pIHsKICAgICAgICByZXR1cm4gdGhpcy5zdGFydC5yb3cgPT0gcm93ICYmIHRoaXMuc3RhcnQuY29sdW1uID09IGNvbHVtbjsKICAgIH07CiAgICBSYW5nZS5wcm90b3R5cGUuc2V0U3RhcnQgPSBmdW5jdGlvbiAocm93LCBjb2x1bW4pIHsKICAgICAgICBpZiAodHlwZW9mIHJvdyA9PSAib2JqZWN0IikgewogICAgICAgICAgICB0aGlzLnN0YXJ0LmNvbHVtbiA9IHJvdy5jb2x1bW47CiAgICAgICAgICAgIHRoaXMuc3RhcnQucm93ID0gcm93LnJvdzsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIHRoaXMuc3RhcnQucm93ID0gcm93OwogICAgICAgICAgICB0aGlzLnN0YXJ0LmNvbHVtbiA9IGNvbHVtbjsKICAgICAgICB9CiAgICB9OwogICAgUmFuZ2UucHJvdG90eXBlLnNldEVuZCA9IGZ1bmN0aW9uIChyb3csIGNvbHVtbikgewogICAgICAgIGlmICh0eXBlb2Ygcm93ID09ICJvYmplY3QiKSB7CiAgICAgICAgICAgIHRoaXMuZW5kLmNvbHVtbiA9IHJvdy5jb2x1bW47CiAgICAgICAgICAgIHRoaXMuZW5kLnJvdyA9IHJvdy5yb3c7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICB0aGlzLmVuZC5yb3cgPSByb3c7CiAgICAgICAgICAgIHRoaXMuZW5kLmNvbHVtbiA9IGNvbHVtbjsKICAgICAgICB9CiAgICB9OwogICAgUmFuZ2UucHJvdG90eXBlLmluc2lkZSA9IGZ1bmN0aW9uIChyb3csIGNvbHVtbikgewogICAgICAgIGlmICh0aGlzLmNvbXBhcmUocm93LCBjb2x1bW4pID09IDApIHsKICAgICAgICAgICAgaWYgKHRoaXMuaXNFbmQocm93LCBjb2x1bW4pIHx8IHRoaXMuaXNTdGFydChyb3csIGNvbHVtbikpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH07CiAgICBSYW5nZS5wcm90b3R5cGUuaW5zaWRlU3RhcnQgPSBmdW5jdGlvbiAocm93LCBjb2x1bW4pIHsKICAgICAgICBpZiAodGhpcy5jb21wYXJlKHJvdywgY29sdW1uKSA9PSAwKSB7CiAgICAgICAgICAgIGlmICh0aGlzLmlzRW5kKHJvdywgY29sdW1uKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfTsKICAgIFJhbmdlLnByb3RvdHlwZS5pbnNpZGVFbmQgPSBmdW5jdGlvbiAocm93LCBjb2x1bW4pIHsKICAgICAgICBpZiAodGhpcy5jb21wYXJlKHJvdywgY29sdW1uKSA9PSAwKSB7CiAgICAgICAgICAgIGlmICh0aGlzLmlzU3RhcnQocm93LCBjb2x1bW4pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9OwogICAgUmFuZ2UucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiAocm93LCBjb2x1bW4pIHsKICAgICAgICBpZiAoIXRoaXMuaXNNdWx0aUxpbmUoKSkgewogICAgICAgICAgICBpZiAocm93ID09PSB0aGlzLnN0YXJ0LnJvdykgewogICAgICAgICAgICAgICAgcmV0dXJuIGNvbHVtbiA8IHRoaXMuc3RhcnQuY29sdW1uID8gLTEgOiAoY29sdW1uID4gdGhpcy5lbmQuY29sdW1uID8gMSA6IDApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChyb3cgPCB0aGlzLnN0YXJ0LnJvdykKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIGlmIChyb3cgPiB0aGlzLmVuZC5yb3cpCiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIGlmICh0aGlzLnN0YXJ0LnJvdyA9PT0gcm93KQogICAgICAgICAgICByZXR1cm4gY29sdW1uID49IHRoaXMuc3RhcnQuY29sdW1uID8gMCA6IC0xOwogICAgICAgIGlmICh0aGlzLmVuZC5yb3cgPT09IHJvdykKICAgICAgICAgICAgcmV0dXJuIGNvbHVtbiA8PSB0aGlzLmVuZC5jb2x1bW4gPyAwIDogMTsKICAgICAgICByZXR1cm4gMDsKICAgIH07CiAgICBSYW5nZS5wcm90b3R5cGUuY29tcGFyZVN0YXJ0ID0gZnVuY3Rpb24gKHJvdywgY29sdW1uKSB7CiAgICAgICAgaWYgKHRoaXMuc3RhcnQucm93ID09IHJvdyAmJiB0aGlzLnN0YXJ0LmNvbHVtbiA9PSBjb2x1bW4pIHsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29tcGFyZShyb3csIGNvbHVtbik7CiAgICAgICAgfQogICAgfTsKICAgIFJhbmdlLnByb3RvdHlwZS5jb21wYXJlRW5kID0gZnVuY3Rpb24gKHJvdywgY29sdW1uKSB7CiAgICAgICAgaWYgKHRoaXMuZW5kLnJvdyA9PSByb3cgJiYgdGhpcy5lbmQuY29sdW1uID09IGNvbHVtbikgewogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbXBhcmUocm93LCBjb2x1bW4pOwogICAgICAgIH0KICAgIH07CiAgICBSYW5nZS5wcm90b3R5cGUuY29tcGFyZUluc2lkZSA9IGZ1bmN0aW9uIChyb3csIGNvbHVtbikgewogICAgICAgIGlmICh0aGlzLmVuZC5yb3cgPT0gcm93ICYmIHRoaXMuZW5kLmNvbHVtbiA9PSBjb2x1bW4pIHsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKHRoaXMuc3RhcnQucm93ID09IHJvdyAmJiB0aGlzLnN0YXJ0LmNvbHVtbiA9PSBjb2x1bW4pIHsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29tcGFyZShyb3csIGNvbHVtbik7CiAgICAgICAgfQogICAgfTsKICAgIFJhbmdlLnByb3RvdHlwZS5jbGlwUm93cyA9IGZ1bmN0aW9uIChmaXJzdFJvdywgbGFzdFJvdykgewogICAgICAgIGlmICh0aGlzLmVuZC5yb3cgPiBsYXN0Um93KQogICAgICAgICAgICB2YXIgZW5kID0geyByb3c6IGxhc3RSb3cgKyAxLCBjb2x1bW46IDAgfTsKICAgICAgICBlbHNlIGlmICh0aGlzLmVuZC5yb3cgPCBmaXJzdFJvdykKICAgICAgICAgICAgdmFyIGVuZCA9IHsgcm93OiBmaXJzdFJvdywgY29sdW1uOiAwIH07CiAgICAgICAgaWYgKHRoaXMuc3RhcnQucm93ID4gbGFzdFJvdykKICAgICAgICAgICAgdmFyIHN0YXJ0ID0geyByb3c6IGxhc3RSb3cgKyAxLCBjb2x1bW46IDAgfTsKICAgICAgICBlbHNlIGlmICh0aGlzLnN0YXJ0LnJvdyA8IGZpcnN0Um93KQogICAgICAgICAgICB2YXIgc3RhcnQgPSB7IHJvdzogZmlyc3RSb3csIGNvbHVtbjogMCB9OwogICAgICAgIHJldHVybiBSYW5nZS5mcm9tUG9pbnRzKHN0YXJ0IHx8IHRoaXMuc3RhcnQsIGVuZCB8fCB0aGlzLmVuZCk7CiAgICB9OwogICAgUmFuZ2UucHJvdG90eXBlLmV4dGVuZCA9IGZ1bmN0aW9uIChyb3csIGNvbHVtbikgewogICAgICAgIHZhciBjbXAgPSB0aGlzLmNvbXBhcmUocm93LCBjb2x1bW4pOwogICAgICAgIGlmIChjbXAgPT0gMCkKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgZWxzZSBpZiAoY21wID09IC0xKQogICAgICAgICAgICB2YXIgc3RhcnQgPSB7IHJvdzogcm93LCBjb2x1bW46IGNvbHVtbiB9OwogICAgICAgIGVsc2UKICAgICAgICAgICAgdmFyIGVuZCA9IHsgcm93OiByb3csIGNvbHVtbjogY29sdW1uIH07CiAgICAgICAgcmV0dXJuIFJhbmdlLmZyb21Qb2ludHMoc3RhcnQgfHwgdGhpcy5zdGFydCwgZW5kIHx8IHRoaXMuZW5kKTsKICAgIH07CiAgICBSYW5nZS5wcm90b3R5cGUuaXNFbXB0eSA9IGZ1bmN0aW9uICgpIHsKICAgICAgICByZXR1cm4gKHRoaXMuc3RhcnQucm93ID09PSB0aGlzLmVuZC5yb3cgJiYgdGhpcy5zdGFydC5jb2x1bW4gPT09IHRoaXMuZW5kLmNvbHVtbik7CiAgICB9OwogICAgUmFuZ2UucHJvdG90eXBlLmlzTXVsdGlMaW5lID0gZnVuY3Rpb24gKCkgewogICAgICAgIHJldHVybiAodGhpcy5zdGFydC5yb3cgIT09IHRoaXMuZW5kLnJvdyk7CiAgICB9OwogICAgUmFuZ2UucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24gKCkgewogICAgICAgIHJldHVybiBSYW5nZS5mcm9tUG9pbnRzKHRoaXMuc3RhcnQsIHRoaXMuZW5kKTsKICAgIH07CiAgICBSYW5nZS5wcm90b3R5cGUuY29sbGFwc2VSb3dzID0gZnVuY3Rpb24gKCkgewogICAgICAgIGlmICh0aGlzLmVuZC5jb2x1bW4gPT0gMCkKICAgICAgICAgICAgcmV0dXJuIG5ldyBSYW5nZSh0aGlzLnN0YXJ0LnJvdywgMCwgTWF0aC5tYXgodGhpcy5zdGFydC5yb3csIHRoaXMuZW5kLnJvdyAtIDEpLCAwKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHJldHVybiBuZXcgUmFuZ2UodGhpcy5zdGFydC5yb3csIDAsIHRoaXMuZW5kLnJvdywgMCk7CiAgICB9OwogICAgUmFuZ2UucHJvdG90eXBlLnRvU2NyZWVuUmFuZ2UgPSBmdW5jdGlvbiAoc2Vzc2lvbikgewogICAgICAgIHZhciBzY3JlZW5Qb3NTdGFydCA9IHNlc3Npb24uZG9jdW1lbnRUb1NjcmVlblBvc2l0aW9uKHRoaXMuc3RhcnQpOwogICAgICAgIHZhciBzY3JlZW5Qb3NFbmQgPSBzZXNzaW9uLmRvY3VtZW50VG9TY3JlZW5Qb3NpdGlvbih0aGlzLmVuZCk7CiAgICAgICAgcmV0dXJuIG5ldyBSYW5nZShzY3JlZW5Qb3NTdGFydC5yb3csIHNjcmVlblBvc1N0YXJ0LmNvbHVtbiwgc2NyZWVuUG9zRW5kLnJvdywgc2NyZWVuUG9zRW5kLmNvbHVtbik7CiAgICB9OwogICAgUmFuZ2UucHJvdG90eXBlLm1vdmVCeSA9IGZ1bmN0aW9uIChyb3csIGNvbHVtbikgewogICAgICAgIHRoaXMuc3RhcnQucm93ICs9IHJvdzsKICAgICAgICB0aGlzLnN0YXJ0LmNvbHVtbiArPSBjb2x1bW47CiAgICAgICAgdGhpcy5lbmQucm93ICs9IHJvdzsKICAgICAgICB0aGlzLmVuZC5jb2x1bW4gKz0gY29sdW1uOwogICAgfTsKICAgIHJldHVybiBSYW5nZTsKfSgpKTsKUmFuZ2UuZnJvbVBvaW50cyA9IGZ1bmN0aW9uIChzdGFydCwgZW5kKSB7CiAgICByZXR1cm4gbmV3IFJhbmdlKHN0YXJ0LnJvdywgc3RhcnQuY29sdW1uLCBlbmQucm93LCBlbmQuY29sdW1uKTsKfTsKUmFuZ2UuY29tcGFyZVBvaW50cyA9IGZ1bmN0aW9uIChwMSwgcDIpIHsKICAgIHJldHVybiBwMS5yb3cgLSBwMi5yb3cgfHwgcDEuY29sdW1uIC0gcDIuY29sdW1uOwp9OwpleHBvcnRzLlJhbmdlID0gUmFuZ2U7Cgp9KTsKCmFjZS5kZWZpbmUoImFjZS9hbmNob3IiLFtdLCBmdW5jdGlvbihyZXF1aXJlLCBleHBvcnRzLCBtb2R1bGUpeyJ1c2Ugc3RyaWN0IjsKdmFyIG9vcCA9IHJlcXVpcmUoIi4vbGliL29vcCIpOwp2YXIgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgiLi9saWIvZXZlbnRfZW1pdHRlciIpLkV2ZW50RW1pdHRlcjsKdmFyIEFuY2hvciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHsKICAgIGZ1bmN0aW9uIEFuY2hvcihkb2MsIHJvdywgY29sdW1uKSB7CiAgICAgICAgdGhpcy4kb25DaGFuZ2UgPSB0aGlzLm9uQ2hhbmdlLmJpbmQodGhpcyk7CiAgICAgICAgdGhpcy5hdHRhY2goZG9jKTsKICAgICAgICBpZiAodHlwZW9mIHJvdyAhPSAibnVtYmVyIikKICAgICAgICAgICAgdGhpcy5zZXRQb3NpdGlvbihyb3cucm93LCByb3cuY29sdW1uKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHRoaXMuc2V0UG9zaXRpb24ocm93LCBjb2x1bW4pOwogICAgfQogICAgQW5jaG9yLnByb3RvdHlwZS5nZXRQb3NpdGlvbiA9IGZ1bmN0aW9uICgpIHsKICAgICAgICByZXR1cm4gdGhpcy4kY2xpcFBvc2l0aW9uVG9Eb2N1bWVudCh0aGlzLnJvdywgdGhpcy5jb2x1bW4pOwogICAgfTsKICAgIEFuY2hvci5wcm90b3R5cGUuZ2V0RG9jdW1lbnQgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuZG9jdW1lbnQ7CiAgICB9OwogICAgQW5jaG9yLnByb3RvdHlwZS5vbkNoYW5nZSA9IGZ1bmN0aW9uIChkZWx0YSkgewogICAgICAgIGlmIChkZWx0YS5zdGFydC5yb3cgPT0gZGVsdGEuZW5kLnJvdyAmJiBkZWx0YS5zdGFydC5yb3cgIT0gdGhpcy5yb3cpCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICBpZiAoZGVsdGEuc3RhcnQucm93ID4gdGhpcy5yb3cpCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB2YXIgcG9pbnQgPSAkZ2V0VHJhbnNmb3JtZWRQb2ludChkZWx0YSwgeyByb3c6IHRoaXMucm93LCBjb2x1bW46IHRoaXMuY29sdW1uIH0sIHRoaXMuJGluc2VydFJpZ2h0KTsKICAgICAgICB0aGlzLnNldFBvc2l0aW9uKHBvaW50LnJvdywgcG9pbnQuY29sdW1uLCB0cnVlKTsKICAgIH07CiAgICBBbmNob3IucHJvdG90eXBlLnNldFBvc2l0aW9uID0gZnVuY3Rpb24gKHJvdywgY29sdW1uLCBub0NsaXApIHsKICAgICAgICB2YXIgcG9zOwogICAgICAgIGlmIChub0NsaXApIHsKICAgICAgICAgICAgcG9zID0gewogICAgICAgICAgICAgICAgcm93OiByb3csCiAgICAgICAgICAgICAgICBjb2x1bW46IGNvbHVtbgogICAgICAgICAgICB9OwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgcG9zID0gdGhpcy4kY2xpcFBvc2l0aW9uVG9Eb2N1bWVudChyb3csIGNvbHVtbik7CiAgICAgICAgfQogICAgICAgIGlmICh0aGlzLnJvdyA9PSBwb3Mucm93ICYmIHRoaXMuY29sdW1uID09IHBvcy5jb2x1bW4pCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB2YXIgb2xkID0gewogICAgICAgICAgICByb3c6IHRoaXMucm93LAogICAgICAgICAgICBjb2x1bW46IHRoaXMuY29sdW1uCiAgICAgICAgfTsKICAgICAgICB0aGlzLnJvdyA9IHBvcy5yb3c7CiAgICAgICAgdGhpcy5jb2x1bW4gPSBwb3MuY29sdW1uOwogICAgICAgIHRoaXMuX3NpZ25hbCgiY2hhbmdlIiwgewogICAgICAgICAgICBvbGQ6IG9sZCwKICAgICAgICAgICAgdmFsdWU6IHBvcwogICAgICAgIH0pOwogICAgfTsKICAgIEFuY2hvci5wcm90b3R5cGUuZGV0YWNoID0gZnVuY3Rpb24gKCkgewogICAgICAgIHRoaXMuZG9jdW1lbnQub2ZmKCJjaGFuZ2UiLCB0aGlzLiRvbkNoYW5nZSk7CiAgICB9OwogICAgQW5jaG9yLnByb3RvdHlwZS5hdHRhY2ggPSBmdW5jdGlvbiAoZG9jKSB7CiAgICAgICAgdGhpcy5kb2N1bWVudCA9IGRvYyB8fCB0aGlzLmRvY3VtZW50OwogICAgICAgIHRoaXMuZG9jdW1lbnQub24oImNoYW5nZSIsIHRoaXMuJG9uQ2hhbmdlKTsKICAgIH07CiAgICBBbmNob3IucHJvdG90eXBlLiRjbGlwUG9zaXRpb25Ub0RvY3VtZW50ID0gZnVuY3Rpb24gKHJvdywgY29sdW1uKSB7CiAgICAgICAgdmFyIHBvcyA9IHt9OwogICAgICAgIGlmIChyb3cgPj0gdGhpcy5kb2N1bWVudC5nZXRMZW5ndGgoKSkgewogICAgICAgICAgICBwb3Mucm93ID0gTWF0aC5tYXgoMCwgdGhpcy5kb2N1bWVudC5nZXRMZW5ndGgoKSAtIDEpOwogICAgICAgICAgICBwb3MuY29sdW1uID0gdGhpcy5kb2N1bWVudC5nZXRMaW5lKHBvcy5yb3cpLmxlbmd0aDsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAocm93IDwgMCkgewogICAgICAgICAgICBwb3Mucm93ID0gMDsKICAgICAgICAgICAgcG9zLmNvbHVtbiA9IDA7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBwb3Mucm93ID0gcm93OwogICAgICAgICAgICBwb3MuY29sdW1uID0gTWF0aC5taW4odGhpcy5kb2N1bWVudC5nZXRMaW5lKHBvcy5yb3cpLmxlbmd0aCwgTWF0aC5tYXgoMCwgY29sdW1uKSk7CiAgICAgICAgfQogICAgICAgIGlmIChjb2x1bW4gPCAwKQogICAgICAgICAgICBwb3MuY29sdW1uID0gMDsKICAgICAgICByZXR1cm4gcG9zOwogICAgfTsKICAgIHJldHVybiBBbmNob3I7Cn0oKSk7CkFuY2hvci5wcm90b3R5cGUuJGluc2VydFJpZ2h0ID0gZmFsc2U7Cm9vcC5pbXBsZW1lbnQoQW5jaG9yLnByb3RvdHlwZSwgRXZlbnRFbWl0dGVyKTsKZnVuY3Rpb24gJHBvaW50c0luT3JkZXIocG9pbnQxLCBwb2ludDIsIGVxdWFsUG9pbnRzSW5PcmRlcikgewogICAgdmFyIGJDb2xJc0FmdGVyID0gZXF1YWxQb2ludHNJbk9yZGVyID8gcG9pbnQxLmNvbHVtbiA8PSBwb2ludDIuY29sdW1uIDogcG9pbnQxLmNvbHVtbiA8IHBvaW50Mi5jb2x1bW47CiAgICByZXR1cm4gKHBvaW50MS5yb3cgPCBwb2ludDIucm93KSB8fCAocG9pbnQxLnJvdyA9PSBwb2ludDIucm93ICYmIGJDb2xJc0FmdGVyKTsKfQpmdW5jdGlvbiAkZ2V0VHJhbnNmb3JtZWRQb2ludChkZWx0YSwgcG9pbnQsIG1vdmVJZkVxdWFsKSB7CiAgICB2YXIgZGVsdGFJc0luc2VydCA9IGRlbHRhLmFjdGlvbiA9PSAiaW5zZXJ0IjsKICAgIHZhciBkZWx0YVJvd1NoaWZ0ID0gKGRlbHRhSXNJbnNlcnQgPyAxIDogLTEpICogKGRlbHRhLmVuZC5yb3cgLSBkZWx0YS5zdGFydC5yb3cpOwogICAgdmFyIGRlbHRhQ29sU2hpZnQgPSAoZGVsdGFJc0luc2VydCA/IDEgOiAtMSkgKiAoZGVsdGEuZW5kLmNvbHVtbiAtIGRlbHRhLnN0YXJ0LmNvbHVtbik7CiAgICB2YXIgZGVsdGFTdGFydCA9IGRlbHRhLnN0YXJ0OwogICAgdmFyIGRlbHRhRW5kID0gZGVsdGFJc0luc2VydCA/IGRlbHRhU3RhcnQgOiBkZWx0YS5lbmQ7IC8vIENvbGxhcHNlIGluc2VydCByYW5nZS4KICAgIGlmICgkcG9pbnRzSW5PcmRlcihwb2ludCwgZGVsdGFTdGFydCwgbW92ZUlmRXF1YWwpKSB7CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgcm93OiBwb2ludC5yb3csCiAgICAgICAgICAgIGNvbHVtbjogcG9pbnQuY29sdW1uCiAgICAgICAgfTsKICAgIH0KICAgIGlmICgkcG9pbnRzSW5PcmRlcihkZWx0YUVuZCwgcG9pbnQsICFtb3ZlSWZFcXVhbCkpIHsKICAgICAgICByZXR1cm4gewogICAgICAgICAgICByb3c6IHBvaW50LnJvdyArIGRlbHRhUm93U2hpZnQsCiAgICAgICAgICAgIGNvbHVtbjogcG9pbnQuY29sdW1uICsgKHBvaW50LnJvdyA9PSBkZWx0YUVuZC5yb3cgPyBkZWx0YUNvbFNoaWZ0IDogMCkKICAgICAgICB9OwogICAgfQogICAgcmV0dXJuIHsKICAgICAgICByb3c6IGRlbHRhU3RhcnQucm93LAogICAgICAgIGNvbHVtbjogZGVsdGFTdGFydC5jb2x1bW4KICAgIH07Cn0KZXhwb3J0cy5BbmNob3IgPSBBbmNob3I7Cgp9KTsKCmFjZS5kZWZpbmUoImFjZS9kb2N1bWVudCIsW10sIGZ1bmN0aW9uKHJlcXVpcmUsIGV4cG9ydHMsIG1vZHVsZSl7InVzZSBzdHJpY3QiOwp2YXIgb29wID0gcmVxdWlyZSgiLi9saWIvb29wIik7CnZhciBhcHBseURlbHRhID0gcmVxdWlyZSgiLi9hcHBseV9kZWx0YSIpLmFwcGx5RGVsdGE7CnZhciBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCIuL2xpYi9ldmVudF9lbWl0dGVyIikuRXZlbnRFbWl0dGVyOwp2YXIgUmFuZ2UgPSByZXF1aXJlKCIuL3JhbmdlIikuUmFuZ2U7CnZhciBBbmNob3IgPSByZXF1aXJlKCIuL2FuY2hvciIpLkFuY2hvcjsKdmFyIERvY3VtZW50ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkgewogICAgZnVuY3Rpb24gRG9jdW1lbnQodGV4dE9yTGluZXMpIHsKICAgICAgICB0aGlzLiRsaW5lcyA9IFsiIl07CiAgICAgICAgaWYgKHRleHRPckxpbmVzLmxlbmd0aCA9PT0gMCkgewogICAgICAgICAgICB0aGlzLiRsaW5lcyA9IFsiIl07CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKEFycmF5LmlzQXJyYXkodGV4dE9yTGluZXMpKSB7CiAgICAgICAgICAgIHRoaXMuaW5zZXJ0TWVyZ2VkTGluZXMoeyByb3c6IDAsIGNvbHVtbjogMCB9LCB0ZXh0T3JMaW5lcyk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICB0aGlzLmluc2VydCh7IHJvdzogMCwgY29sdW1uOiAwIH0sIHRleHRPckxpbmVzKTsKICAgICAgICB9CiAgICB9CiAgICBEb2N1bWVudC5wcm90b3R5cGUuc2V0VmFsdWUgPSBmdW5jdGlvbiAodGV4dCkgewogICAgICAgIHZhciBsZW4gPSB0aGlzLmdldExlbmd0aCgpIC0gMTsKICAgICAgICB0aGlzLnJlbW92ZShuZXcgUmFuZ2UoMCwgMCwgbGVuLCB0aGlzLmdldExpbmUobGVuKS5sZW5ndGgpKTsKICAgICAgICB0aGlzLmluc2VydCh7IHJvdzogMCwgY29sdW1uOiAwIH0sIHRleHQgfHwgIiIpOwogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS5nZXRWYWx1ZSA9IGZ1bmN0aW9uICgpIHsKICAgICAgICByZXR1cm4gdGhpcy5nZXRBbGxMaW5lcygpLmpvaW4odGhpcy5nZXROZXdMaW5lQ2hhcmFjdGVyKCkpOwogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS5jcmVhdGVBbmNob3IgPSBmdW5jdGlvbiAocm93LCBjb2x1bW4pIHsKICAgICAgICByZXR1cm4gbmV3IEFuY2hvcih0aGlzLCByb3csIGNvbHVtbik7CiAgICB9OwogICAgRG9jdW1lbnQucHJvdG90eXBlLiRkZXRlY3ROZXdMaW5lID0gZnVuY3Rpb24gKHRleHQpIHsKICAgICAgICB2YXIgbWF0Y2ggPSB0ZXh0Lm1hdGNoKC9eLio/KFxyXG58XHJ8XG4pL20pOwogICAgICAgIHRoaXMuJGF1dG9OZXdMaW5lID0gbWF0Y2ggPyBtYXRjaFsxXSA6ICJcbiI7CiAgICAgICAgdGhpcy5fc2lnbmFsKCJjaGFuZ2VOZXdMaW5lTW9kZSIpOwogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS5nZXROZXdMaW5lQ2hhcmFjdGVyID0gZnVuY3Rpb24gKCkgewogICAgICAgIHN3aXRjaCAodGhpcy4kbmV3TGluZU1vZGUpIHsKICAgICAgICAgICAgY2FzZSAid2luZG93cyI6CiAgICAgICAgICAgICAgICByZXR1cm4gIlxyXG4iOwogICAgICAgICAgICBjYXNlICJ1bml4IjoKICAgICAgICAgICAgICAgIHJldHVybiAiXG4iOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuJGF1dG9OZXdMaW5lIHx8ICJcbiI7CiAgICAgICAgfQogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS5zZXROZXdMaW5lTW9kZSA9IGZ1bmN0aW9uIChuZXdMaW5lTW9kZSkgewogICAgICAgIGlmICh0aGlzLiRuZXdMaW5lTW9kZSA9PT0gbmV3TGluZU1vZGUpCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB0aGlzLiRuZXdMaW5lTW9kZSA9IG5ld0xpbmVNb2RlOwogICAgICAgIHRoaXMuX3NpZ25hbCgiY2hhbmdlTmV3TGluZU1vZGUiKTsKICAgIH07CiAgICBEb2N1bWVudC5wcm90b3R5cGUuZ2V0TmV3TGluZU1vZGUgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuJG5ld0xpbmVNb2RlOwogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS5pc05ld0xpbmUgPSBmdW5jdGlvbiAodGV4dCkgewogICAgICAgIHJldHVybiAodGV4dCA9PSAiXHJcbiIgfHwgdGV4dCA9PSAiXHIiIHx8IHRleHQgPT0gIlxuIik7CiAgICB9OwogICAgRG9jdW1lbnQucHJvdG90eXBlLmdldExpbmUgPSBmdW5jdGlvbiAocm93KSB7CiAgICAgICAgcmV0dXJuIHRoaXMuJGxpbmVzW3Jvd10gfHwgIiI7CiAgICB9OwogICAgRG9jdW1lbnQucHJvdG90eXBlLmdldExpbmVzID0gZnVuY3Rpb24gKGZpcnN0Um93LCBsYXN0Um93KSB7CiAgICAgICAgcmV0dXJuIHRoaXMuJGxpbmVzLnNsaWNlKGZpcnN0Um93LCBsYXN0Um93ICsgMSk7CiAgICB9OwogICAgRG9jdW1lbnQucHJvdG90eXBlLmdldEFsbExpbmVzID0gZnVuY3Rpb24gKCkgewogICAgICAgIHJldHVybiB0aGlzLmdldExpbmVzKDAsIHRoaXMuZ2V0TGVuZ3RoKCkpOwogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS5nZXRMZW5ndGggPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuJGxpbmVzLmxlbmd0aDsKICAgIH07CiAgICBEb2N1bWVudC5wcm90b3R5cGUuZ2V0VGV4dFJhbmdlID0gZnVuY3Rpb24gKHJhbmdlKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0TGluZXNGb3JSYW5nZShyYW5nZSkuam9pbih0aGlzLmdldE5ld0xpbmVDaGFyYWN0ZXIoKSk7CiAgICB9OwogICAgRG9jdW1lbnQucHJvdG90eXBlLmdldExpbmVzRm9yUmFuZ2UgPSBmdW5jdGlvbiAocmFuZ2UpIHsKICAgICAgICB2YXIgbGluZXM7CiAgICAgICAgaWYgKHJhbmdlLnN0YXJ0LnJvdyA9PT0gcmFuZ2UuZW5kLnJvdykgewogICAgICAgICAgICBsaW5lcyA9IFt0aGlzLmdldExpbmUocmFuZ2Uuc3RhcnQucm93KS5zdWJzdHJpbmcocmFuZ2Uuc3RhcnQuY29sdW1uLCByYW5nZS5lbmQuY29sdW1uKV07CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBsaW5lcyA9IHRoaXMuZ2V0TGluZXMocmFuZ2Uuc3RhcnQucm93LCByYW5nZS5lbmQucm93KTsKICAgICAgICAgICAgbGluZXNbMF0gPSAobGluZXNbMF0gfHwgIiIpLnN1YnN0cmluZyhyYW5nZS5zdGFydC5jb2x1bW4pOwogICAgICAgICAgICB2YXIgbCA9IGxpbmVzLmxlbmd0aCAtIDE7CiAgICAgICAgICAgIGlmIChyYW5nZS5lbmQucm93IC0gcmFuZ2Uuc3RhcnQucm93ID09IGwpCiAgICAgICAgICAgICAgICBsaW5lc1tsXSA9IGxpbmVzW2xdLnN1YnN0cmluZygwLCByYW5nZS5lbmQuY29sdW1uKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGxpbmVzOwogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS5pbnNlcnRMaW5lcyA9IGZ1bmN0aW9uIChyb3csIGxpbmVzKSB7CiAgICAgICAgY29uc29sZS53YXJuKCJVc2Ugb2YgZG9jdW1lbnQuaW5zZXJ0TGluZXMgaXMgZGVwcmVjYXRlZC4gVXNlIHRoZSBpbnNlcnRGdWxsTGluZXMgbWV0aG9kIGluc3RlYWQuIik7CiAgICAgICAgcmV0dXJuIHRoaXMuaW5zZXJ0RnVsbExpbmVzKHJvdywgbGluZXMpOwogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS5yZW1vdmVMaW5lcyA9IGZ1bmN0aW9uIChmaXJzdFJvdywgbGFzdFJvdykgewogICAgICAgIGNvbnNvbGUud2FybigiVXNlIG9mIGRvY3VtZW50LnJlbW92ZUxpbmVzIGlzIGRlcHJlY2F0ZWQuIFVzZSB0aGUgcmVtb3ZlRnVsbExpbmVzIG1ldGhvZCBpbnN0ZWFkLiIpOwogICAgICAgIHJldHVybiB0aGlzLnJlbW92ZUZ1bGxMaW5lcyhmaXJzdFJvdywgbGFzdFJvdyk7CiAgICB9OwogICAgRG9jdW1lbnQucHJvdG90eXBlLmluc2VydE5ld0xpbmUgPSBmdW5jdGlvbiAocG9zaXRpb24pIHsKICAgICAgICBjb25zb2xlLndhcm4oIlVzZSBvZiBkb2N1bWVudC5pbnNlcnROZXdMaW5lIGlzIGRlcHJlY2F0ZWQuIFVzZSBpbnNlcnRNZXJnZWRMaW5lcyhwb3NpdGlvbiwgWycnLCAnJ10pIGluc3RlYWQuIik7CiAgICAgICAgcmV0dXJuIHRoaXMuaW5zZXJ0TWVyZ2VkTGluZXMocG9zaXRpb24sIFsiIiwgIiJdKTsKICAgIH07CiAgICBEb2N1bWVudC5wcm90b3R5cGUuaW5zZXJ0ID0gZnVuY3Rpb24gKHBvc2l0aW9uLCB0ZXh0KSB7CiAgICAgICAgaWYgKHRoaXMuZ2V0TGVuZ3RoKCkgPD0gMSkKICAgICAgICAgICAgdGhpcy4kZGV0ZWN0TmV3TGluZSh0ZXh0KTsKICAgICAgICByZXR1cm4gdGhpcy5pbnNlcnRNZXJnZWRMaW5lcyhwb3NpdGlvbiwgdGhpcy4kc3BsaXQodGV4dCkpOwogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS5pbnNlcnRJbkxpbmUgPSBmdW5jdGlvbiAocG9zaXRpb24sIHRleHQpIHsKICAgICAgICB2YXIgc3RhcnQgPSB0aGlzLmNsaXBwZWRQb3MocG9zaXRpb24ucm93LCBwb3NpdGlvbi5jb2x1bW4pOwogICAgICAgIHZhciBlbmQgPSB0aGlzLnBvcyhwb3NpdGlvbi5yb3csIHBvc2l0aW9uLmNvbHVtbiArIHRleHQubGVuZ3RoKTsKICAgICAgICB0aGlzLmFwcGx5RGVsdGEoewogICAgICAgICAgICBzdGFydDogc3RhcnQsCiAgICAgICAgICAgIGVuZDogZW5kLAogICAgICAgICAgICBhY3Rpb246ICJpbnNlcnQiLAogICAgICAgICAgICBsaW5lczogW3RleHRdCiAgICAgICAgfSwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIHRoaXMuY2xvbmVQb3MoZW5kKTsKICAgIH07CiAgICBEb2N1bWVudC5wcm90b3R5cGUuY2xpcHBlZFBvcyA9IGZ1bmN0aW9uIChyb3csIGNvbHVtbikgewogICAgICAgIHZhciBsZW5ndGggPSB0aGlzLmdldExlbmd0aCgpOwogICAgICAgIGlmIChyb3cgPT09IHVuZGVmaW5lZCkgewogICAgICAgICAgICByb3cgPSBsZW5ndGg7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKHJvdyA8IDApIHsKICAgICAgICAgICAgcm93ID0gMDsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAocm93ID49IGxlbmd0aCkgewogICAgICAgICAgICByb3cgPSBsZW5ndGggLSAxOwogICAgICAgICAgICBjb2x1bW4gPSB1bmRlZmluZWQ7CiAgICAgICAgfQogICAgICAgIHZhciBsaW5lID0gdGhpcy5nZXRMaW5lKHJvdyk7CiAgICAgICAgaWYgKGNvbHVtbiA9PSB1bmRlZmluZWQpCiAgICAgICAgICAgIGNvbHVtbiA9IGxpbmUubGVuZ3RoOwogICAgICAgIGNvbHVtbiA9IE1hdGgubWluKE1hdGgubWF4KGNvbHVtbiwgMCksIGxpbmUubGVuZ3RoKTsKICAgICAgICByZXR1cm4geyByb3c6IHJvdywgY29sdW1uOiBjb2x1bW4gfTsKICAgIH07CiAgICBEb2N1bWVudC5wcm90b3R5cGUuY2xvbmVQb3MgPSBmdW5jdGlvbiAocG9zKSB7CiAgICAgICAgcmV0dXJuIHsgcm93OiBwb3Mucm93LCBjb2x1bW46IHBvcy5jb2x1bW4gfTsKICAgIH07CiAgICBEb2N1bWVudC5wcm90b3R5cGUucG9zID0gZnVuY3Rpb24gKHJvdywgY29sdW1uKSB7CiAgICAgICAgcmV0dXJuIHsgcm93OiByb3csIGNvbHVtbjogY29sdW1uIH07CiAgICB9OwogICAgRG9jdW1lbnQucHJvdG90eXBlLiRjbGlwUG9zaXRpb24gPSBmdW5jdGlvbiAocG9zaXRpb24pIHsKICAgICAgICB2YXIgbGVuZ3RoID0gdGhpcy5nZXRMZW5ndGgoKTsKICAgICAgICBpZiAocG9zaXRpb24ucm93ID49IGxlbmd0aCkgewogICAgICAgICAgICBwb3NpdGlvbi5yb3cgPSBNYXRoLm1heCgwLCBsZW5ndGggLSAxKTsKICAgICAgICAgICAgcG9zaXRpb24uY29sdW1uID0gdGhpcy5nZXRMaW5lKGxlbmd0aCAtIDEpLmxlbmd0aDsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIHBvc2l0aW9uLnJvdyA9IE1hdGgubWF4KDAsIHBvc2l0aW9uLnJvdyk7CiAgICAgICAgICAgIHBvc2l0aW9uLmNvbHVtbiA9IE1hdGgubWluKE1hdGgubWF4KHBvc2l0aW9uLmNvbHVtbiwgMCksIHRoaXMuZ2V0TGluZShwb3NpdGlvbi5yb3cpLmxlbmd0aCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBwb3NpdGlvbjsKICAgIH07CiAgICBEb2N1bWVudC5wcm90b3R5cGUuaW5zZXJ0RnVsbExpbmVzID0gZnVuY3Rpb24gKHJvdywgbGluZXMpIHsKICAgICAgICByb3cgPSBNYXRoLm1pbihNYXRoLm1heChyb3csIDApLCB0aGlzLmdldExlbmd0aCgpKTsKICAgICAgICB2YXIgY29sdW1uID0gMDsKICAgICAgICBpZiAocm93IDwgdGhpcy5nZXRMZW5ndGgoKSkgewogICAgICAgICAgICBsaW5lcyA9IGxpbmVzLmNvbmNhdChbIiJdKTsKICAgICAgICAgICAgY29sdW1uID0gMDsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGxpbmVzID0gWyIiXS5jb25jYXQobGluZXMpOwogICAgICAgICAgICByb3ctLTsKICAgICAgICAgICAgY29sdW1uID0gdGhpcy4kbGluZXNbcm93XS5sZW5ndGg7CiAgICAgICAgfQogICAgICAgIHRoaXMuaW5zZXJ0TWVyZ2VkTGluZXMoeyByb3c6IHJvdywgY29sdW1uOiBjb2x1bW4gfSwgbGluZXMpOwogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS5pbnNlcnRNZXJnZWRMaW5lcyA9IGZ1bmN0aW9uIChwb3NpdGlvbiwgbGluZXMpIHsKICAgICAgICB2YXIgc3RhcnQgPSB0aGlzLmNsaXBwZWRQb3MocG9zaXRpb24ucm93LCBwb3NpdGlvbi5jb2x1bW4pOwogICAgICAgIHZhciBlbmQgPSB7CiAgICAgICAgICAgIHJvdzogc3RhcnQucm93ICsgbGluZXMubGVuZ3RoIC0gMSwKICAgICAgICAgICAgY29sdW1uOiAobGluZXMubGVuZ3RoID09IDEgPyBzdGFydC5jb2x1bW4gOiAwKSArIGxpbmVzW2xpbmVzLmxlbmd0aCAtIDFdLmxlbmd0aAogICAgICAgIH07CiAgICAgICAgdGhpcy5hcHBseURlbHRhKHsKICAgICAgICAgICAgc3RhcnQ6IHN0YXJ0LAogICAgICAgICAgICBlbmQ6IGVuZCwKICAgICAgICAgICAgYWN0aW9uOiAiaW5zZXJ0IiwKICAgICAgICAgICAgbGluZXM6IGxpbmVzCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIHRoaXMuY2xvbmVQb3MoZW5kKTsKICAgIH07CiAgICBEb2N1bWVudC5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24gKHJhbmdlKSB7CiAgICAgICAgdmFyIHN0YXJ0ID0gdGhpcy5jbGlwcGVkUG9zKHJhbmdlLnN0YXJ0LnJvdywgcmFuZ2Uuc3RhcnQuY29sdW1uKTsKICAgICAgICB2YXIgZW5kID0gdGhpcy5jbGlwcGVkUG9zKHJhbmdlLmVuZC5yb3csIHJhbmdlLmVuZC5jb2x1bW4pOwogICAgICAgIHRoaXMuYXBwbHlEZWx0YSh7CiAgICAgICAgICAgIHN0YXJ0OiBzdGFydCwKICAgICAgICAgICAgZW5kOiBlbmQsCiAgICAgICAgICAgIGFjdGlvbjogInJlbW92ZSIsCiAgICAgICAgICAgIGxpbmVzOiB0aGlzLmdldExpbmVzRm9yUmFuZ2UoeyBzdGFydDogc3RhcnQsIGVuZDogZW5kIH0pCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIHRoaXMuY2xvbmVQb3Moc3RhcnQpOwogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS5yZW1vdmVJbkxpbmUgPSBmdW5jdGlvbiAocm93LCBzdGFydENvbHVtbiwgZW5kQ29sdW1uKSB7CiAgICAgICAgdmFyIHN0YXJ0ID0gdGhpcy5jbGlwcGVkUG9zKHJvdywgc3RhcnRDb2x1bW4pOwogICAgICAgIHZhciBlbmQgPSB0aGlzLmNsaXBwZWRQb3Mocm93LCBlbmRDb2x1bW4pOwogICAgICAgIHRoaXMuYXBwbHlEZWx0YSh7CiAgICAgICAgICAgIHN0YXJ0OiBzdGFydCwKICAgICAgICAgICAgZW5kOiBlbmQsCiAgICAgICAgICAgIGFjdGlvbjogInJlbW92ZSIsCiAgICAgICAgICAgIGxpbmVzOiB0aGlzLmdldExpbmVzRm9yUmFuZ2UoeyBzdGFydDogc3RhcnQsIGVuZDogZW5kIH0pCiAgICAgICAgfSwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIHRoaXMuY2xvbmVQb3Moc3RhcnQpOwogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS5yZW1vdmVGdWxsTGluZXMgPSBmdW5jdGlvbiAoZmlyc3RSb3csIGxhc3RSb3cpIHsKICAgICAgICBmaXJzdFJvdyA9IE1hdGgubWluKE1hdGgubWF4KDAsIGZpcnN0Um93KSwgdGhpcy5nZXRMZW5ndGgoKSAtIDEpOwogICAgICAgIGxhc3RSb3cgPSBNYXRoLm1pbihNYXRoLm1heCgwLCBsYXN0Um93KSwgdGhpcy5nZXRMZW5ndGgoKSAtIDEpOwogICAgICAgIHZhciBkZWxldGVGaXJzdE5ld0xpbmUgPSBsYXN0Um93ID09IHRoaXMuZ2V0TGVuZ3RoKCkgLSAxICYmIGZpcnN0Um93ID4gMDsKICAgICAgICB2YXIgZGVsZXRlTGFzdE5ld0xpbmUgPSBsYXN0Um93IDwgdGhpcy5nZXRMZW5ndGgoKSAtIDE7CiAgICAgICAgdmFyIHN0YXJ0Um93ID0gKGRlbGV0ZUZpcnN0TmV3TGluZSA/IGZpcnN0Um93IC0gMSA6IGZpcnN0Um93KTsKICAgICAgICB2YXIgc3RhcnRDb2wgPSAoZGVsZXRlRmlyc3ROZXdMaW5lID8gdGhpcy5nZXRMaW5lKHN0YXJ0Um93KS5sZW5ndGggOiAwKTsKICAgICAgICB2YXIgZW5kUm93ID0gKGRlbGV0ZUxhc3ROZXdMaW5lID8gbGFzdFJvdyArIDEgOiBsYXN0Um93KTsKICAgICAgICB2YXIgZW5kQ29sID0gKGRlbGV0ZUxhc3ROZXdMaW5lID8gMCA6IHRoaXMuZ2V0TGluZShlbmRSb3cpLmxlbmd0aCk7CiAgICAgICAgdmFyIHJhbmdlID0gbmV3IFJhbmdlKHN0YXJ0Um93LCBzdGFydENvbCwgZW5kUm93LCBlbmRDb2wpOwogICAgICAgIHZhciBkZWxldGVkTGluZXMgPSB0aGlzLiRsaW5lcy5zbGljZShmaXJzdFJvdywgbGFzdFJvdyArIDEpOwogICAgICAgIHRoaXMuYXBwbHlEZWx0YSh7CiAgICAgICAgICAgIHN0YXJ0OiByYW5nZS5zdGFydCwKICAgICAgICAgICAgZW5kOiByYW5nZS5lbmQsCiAgICAgICAgICAgIGFjdGlvbjogInJlbW92ZSIsCiAgICAgICAgICAgIGxpbmVzOiB0aGlzLmdldExpbmVzRm9yUmFuZ2UocmFuZ2UpCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIGRlbGV0ZWRMaW5lczsKICAgIH07CiAgICBEb2N1bWVudC5wcm90b3R5cGUucmVtb3ZlTmV3TGluZSA9IGZ1bmN0aW9uIChyb3cpIHsKICAgICAgICBpZiAocm93IDwgdGhpcy5nZXRMZW5ndGgoKSAtIDEgJiYgcm93ID49IDApIHsKICAgICAgICAgICAgdGhpcy5hcHBseURlbHRhKHsKICAgICAgICAgICAgICAgIHN0YXJ0OiB0aGlzLnBvcyhyb3csIHRoaXMuZ2V0TGluZShyb3cpLmxlbmd0aCksCiAgICAgICAgICAgICAgICBlbmQ6IHRoaXMucG9zKHJvdyArIDEsIDApLAogICAgICAgICAgICAgICAgYWN0aW9uOiAicmVtb3ZlIiwKICAgICAgICAgICAgICAgIGxpbmVzOiBbIiIsICIiXQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9OwogICAgRG9jdW1lbnQucHJvdG90eXBlLnJlcGxhY2UgPSBmdW5jdGlvbiAocmFuZ2UsIHRleHQpIHsKICAgICAgICBpZiAoIShyYW5nZSBpbnN0YW5jZW9mIFJhbmdlKSkKICAgICAgICAgICAgcmFuZ2UgPSBSYW5nZS5mcm9tUG9pbnRzKHJhbmdlLnN0YXJ0LCByYW5nZS5lbmQpOwogICAgICAgIGlmICh0ZXh0Lmxlbmd0aCA9PT0gMCAmJiByYW5nZS5pc0VtcHR5KCkpCiAgICAgICAgICAgIHJldHVybiByYW5nZS5zdGFydDsKICAgICAgICBpZiAodGV4dCA9PSB0aGlzLmdldFRleHRSYW5nZShyYW5nZSkpCiAgICAgICAgICAgIHJldHVybiByYW5nZS5lbmQ7CiAgICAgICAgdGhpcy5yZW1vdmUocmFuZ2UpOwogICAgICAgIHZhciBlbmQ7CiAgICAgICAgaWYgKHRleHQpIHsKICAgICAgICAgICAgZW5kID0gdGhpcy5pbnNlcnQocmFuZ2Uuc3RhcnQsIHRleHQpOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgZW5kID0gcmFuZ2Uuc3RhcnQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiBlbmQ7CiAgICB9OwogICAgRG9jdW1lbnQucHJvdG90eXBlLmFwcGx5RGVsdGFzID0gZnVuY3Rpb24gKGRlbHRhcykgewogICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGVsdGFzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHRoaXMuYXBwbHlEZWx0YShkZWx0YXNbaV0pOwogICAgICAgIH0KICAgIH07CiAgICBEb2N1bWVudC5wcm90b3R5cGUucmV2ZXJ0RGVsdGFzID0gZnVuY3Rpb24gKGRlbHRhcykgewogICAgICAgIGZvciAodmFyIGkgPSBkZWx0YXMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHsKICAgICAgICAgICAgdGhpcy5yZXZlcnREZWx0YShkZWx0YXNbaV0pOwogICAgICAgIH0KICAgIH07CiAgICBEb2N1bWVudC5wcm90b3R5cGUuYXBwbHlEZWx0YSA9IGZ1bmN0aW9uIChkZWx0YSwgZG9Ob3RWYWxpZGF0ZSkgewogICAgICAgIHZhciBpc0luc2VydCA9IGRlbHRhLmFjdGlvbiA9PSAiaW5zZXJ0IjsKICAgICAgICBpZiAoaXNJbnNlcnQgPyBkZWx0YS5saW5lcy5sZW5ndGggPD0gMSAmJiAhZGVsdGEubGluZXNbMF0KICAgICAgICAgICAgOiAhUmFuZ2UuY29tcGFyZVBvaW50cyhkZWx0YS5zdGFydCwgZGVsdGEuZW5kKSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGlmIChpc0luc2VydCAmJiBkZWx0YS5saW5lcy5sZW5ndGggPiAyMDAwMCkgewogICAgICAgICAgICB0aGlzLiRzcGxpdEFuZGFwcGx5TGFyZ2VEZWx0YShkZWx0YSwgMjAwMDApOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgYXBwbHlEZWx0YSh0aGlzLiRsaW5lcywgZGVsdGEsIGRvTm90VmFsaWRhdGUpOwogICAgICAgICAgICB0aGlzLl9zaWduYWwoImNoYW5nZSIsIGRlbHRhKTsKICAgICAgICB9CiAgICB9OwogICAgRG9jdW1lbnQucHJvdG90eXBlLiRzYWZlQXBwbHlEZWx0YSA9IGZ1bmN0aW9uIChkZWx0YSkgewogICAgICAgIHZhciBkb2NMZW5ndGggPSB0aGlzLiRsaW5lcy5sZW5ndGg7CiAgICAgICAgaWYgKGRlbHRhLmFjdGlvbiA9PSAicmVtb3ZlIiAmJiBkZWx0YS5zdGFydC5yb3cgPCBkb2NMZW5ndGggJiYgZGVsdGEuZW5kLnJvdyA8IGRvY0xlbmd0aAogICAgICAgICAgICB8fCBkZWx0YS5hY3Rpb24gPT0gImluc2VydCIgJiYgZGVsdGEuc3RhcnQucm93IDw9IGRvY0xlbmd0aCkgewogICAgICAgICAgICB0aGlzLmFwcGx5RGVsdGEoZGVsdGEpOwogICAgICAgIH0KICAgIH07CiAgICBEb2N1bWVudC5wcm90b3R5cGUuJHNwbGl0QW5kYXBwbHlMYXJnZURlbHRhID0gZnVuY3Rpb24gKGRlbHRhLCBNQVgpIHsKICAgICAgICB2YXIgbGluZXMgPSBkZWx0YS5saW5lczsKICAgICAgICB2YXIgbCA9IGxpbmVzLmxlbmd0aCAtIE1BWCArIDE7CiAgICAgICAgdmFyIHJvdyA9IGRlbHRhLnN0YXJ0LnJvdzsKICAgICAgICB2YXIgY29sdW1uID0gZGVsdGEuc3RhcnQuY29sdW1uOwogICAgICAgIGZvciAodmFyIGZyb20gPSAwLCB0byA9IDA7IGZyb20gPCBsOyBmcm9tID0gdG8pIHsKICAgICAgICAgICAgdG8gKz0gTUFYIC0gMTsKICAgICAgICAgICAgdmFyIGNodW5rID0gbGluZXMuc2xpY2UoZnJvbSwgdG8pOwogICAgICAgICAgICBjaHVuay5wdXNoKCIiKTsKICAgICAgICAgICAgdGhpcy5hcHBseURlbHRhKHsKICAgICAgICAgICAgICAgIHN0YXJ0OiB0aGlzLnBvcyhyb3cgKyBmcm9tLCBjb2x1bW4pLAogICAgICAgICAgICAgICAgZW5kOiB0aGlzLnBvcyhyb3cgKyB0bywgY29sdW1uID0gMCksCiAgICAgICAgICAgICAgICBhY3Rpb246IGRlbHRhLmFjdGlvbiwKICAgICAgICAgICAgICAgIGxpbmVzOiBjaHVuawogICAgICAgICAgICB9LCB0cnVlKTsKICAgICAgICB9CiAgICAgICAgZGVsdGEubGluZXMgPSBsaW5lcy5zbGljZShmcm9tKTsKICAgICAgICBkZWx0YS5zdGFydC5yb3cgPSByb3cgKyBmcm9tOwogICAgICAgIGRlbHRhLnN0YXJ0LmNvbHVtbiA9IGNvbHVtbjsKICAgICAgICB0aGlzLmFwcGx5RGVsdGEoZGVsdGEsIHRydWUpOwogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS5yZXZlcnREZWx0YSA9IGZ1bmN0aW9uIChkZWx0YSkgewogICAgICAgIHRoaXMuJHNhZmVBcHBseURlbHRhKHsKICAgICAgICAgICAgc3RhcnQ6IHRoaXMuY2xvbmVQb3MoZGVsdGEuc3RhcnQpLAogICAgICAgICAgICBlbmQ6IHRoaXMuY2xvbmVQb3MoZGVsdGEuZW5kKSwKICAgICAgICAgICAgYWN0aW9uOiAoZGVsdGEuYWN0aW9uID09ICJpbnNlcnQiID8gInJlbW92ZSIgOiAiaW5zZXJ0IiksCiAgICAgICAgICAgIGxpbmVzOiBkZWx0YS5saW5lcy5zbGljZSgpCiAgICAgICAgfSk7CiAgICB9OwogICAgRG9jdW1lbnQucHJvdG90eXBlLmluZGV4VG9Qb3NpdGlvbiA9IGZ1bmN0aW9uIChpbmRleCwgc3RhcnRSb3cpIHsKICAgICAgICB2YXIgbGluZXMgPSB0aGlzLiRsaW5lcyB8fCB0aGlzLmdldEFsbExpbmVzKCk7CiAgICAgICAgdmFyIG5ld2xpbmVMZW5ndGggPSB0aGlzLmdldE5ld0xpbmVDaGFyYWN0ZXIoKS5sZW5ndGg7CiAgICAgICAgZm9yICh2YXIgaSA9IHN0YXJ0Um93IHx8IDAsIGwgPSBsaW5lcy5sZW5ndGg7IGkgPCBsOyBpKyspIHsKICAgICAgICAgICAgaW5kZXggLT0gbGluZXNbaV0ubGVuZ3RoICsgbmV3bGluZUxlbmd0aDsKICAgICAgICAgICAgaWYgKGluZGV4IDwgMCkKICAgICAgICAgICAgICAgIHJldHVybiB7IHJvdzogaSwgY29sdW1uOiBpbmRleCArIGxpbmVzW2ldLmxlbmd0aCArIG5ld2xpbmVMZW5ndGggfTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHsgcm93OiBsIC0gMSwgY29sdW1uOiBpbmRleCArIGxpbmVzW2wgLSAxXS5sZW5ndGggKyBuZXdsaW5lTGVuZ3RoIH07CiAgICB9OwogICAgRG9jdW1lbnQucHJvdG90eXBlLnBvc2l0aW9uVG9JbmRleCA9IGZ1bmN0aW9uIChwb3MsIHN0YXJ0Um93KSB7CiAgICAgICAgdmFyIGxpbmVzID0gdGhpcy4kbGluZXMgfHwgdGhpcy5nZXRBbGxMaW5lcygpOwogICAgICAgIHZhciBuZXdsaW5lTGVuZ3RoID0gdGhpcy5nZXROZXdMaW5lQ2hhcmFjdGVyKCkubGVuZ3RoOwogICAgICAgIHZhciBpbmRleCA9IDA7CiAgICAgICAgdmFyIHJvdyA9IE1hdGgubWluKHBvcy5yb3csIGxpbmVzLmxlbmd0aCk7CiAgICAgICAgZm9yICh2YXIgaSA9IHN0YXJ0Um93IHx8IDA7IGkgPCByb3c7ICsraSkKICAgICAgICAgICAgaW5kZXggKz0gbGluZXNbaV0ubGVuZ3RoICsgbmV3bGluZUxlbmd0aDsKICAgICAgICByZXR1cm4gaW5kZXggKyBwb3MuY29sdW1uOwogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS4kc3BsaXQgPSBmdW5jdGlvbiAodGV4dCkgewogICAgICAgIHJldHVybiB0ZXh0LnNwbGl0KC9cclxufFxyfFxuLyk7CiAgICB9OwogICAgcmV0dXJuIERvY3VtZW50Owp9KCkpOwpEb2N1bWVudC5wcm90b3R5cGUuJGF1dG9OZXdMaW5lID0gIiI7CkRvY3VtZW50LnByb3RvdHlwZS4kbmV3TGluZU1vZGUgPSAiYXV0byI7Cm9vcC5pbXBsZW1lbnQoRG9jdW1lbnQucHJvdG90eXBlLCBFdmVudEVtaXR0ZXIpOwpleHBvcnRzLkRvY3VtZW50ID0gRG9jdW1lbnQ7Cgp9KTsKCmFjZS5kZWZpbmUoImFjZS9saWIvZGVlcF9jb3B5IixbXSwgZnVuY3Rpb24ocmVxdWlyZSwgZXhwb3J0cywgbW9kdWxlKXtleHBvcnRzLmRlZXBDb3B5ID0gZnVuY3Rpb24gZGVlcENvcHkob2JqKSB7CiAgICBpZiAodHlwZW9mIG9iaiAhPT0gIm9iamVjdCIgfHwgIW9iaikKICAgICAgICByZXR1cm4gb2JqOwogICAgdmFyIGNvcHk7CiAgICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7CiAgICAgICAgY29weSA9IFtdOwogICAgICAgIGZvciAodmFyIGtleSA9IDA7IGtleSA8IG9iai5sZW5ndGg7IGtleSsrKSB7CiAgICAgICAgICAgIGNvcHlba2V5XSA9IGRlZXBDb3B5KG9ialtrZXldKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvcHk7CiAgICB9CiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iaikgIT09ICJbb2JqZWN0IE9iamVjdF0iKQogICAgICAgIHJldHVybiBvYmo7CiAgICBjb3B5ID0ge307CiAgICBmb3IgKHZhciBrZXkgaW4gb2JqKQogICAgICAgIGNvcHlba2V5XSA9IGRlZXBDb3B5KG9ialtrZXldKTsKICAgIHJldHVybiBjb3B5Owp9OwoKfSk7CgphY2UuZGVmaW5lKCJhY2UvbGliL2xhbmciLFtdLCBmdW5jdGlvbihyZXF1aXJlLCBleHBvcnRzLCBtb2R1bGUpeyJ1c2Ugc3RyaWN0IjsKZXhwb3J0cy5sYXN0ID0gZnVuY3Rpb24gKGEpIHsKICAgIHJldHVybiBhW2EubGVuZ3RoIC0gMV07Cn07CmV4cG9ydHMuc3RyaW5nUmV2ZXJzZSA9IGZ1bmN0aW9uIChzdHJpbmcpIHsKICAgIHJldHVybiBzdHJpbmcuc3BsaXQoIiIpLnJldmVyc2UoKS5qb2luKCIiKTsKfTsKZXhwb3J0cy5zdHJpbmdSZXBlYXQgPSBmdW5jdGlvbiAoc3RyaW5nLCBjb3VudCkgewogICAgdmFyIHJlc3VsdCA9ICcnOwogICAgd2hpbGUgKGNvdW50ID4gMCkgewogICAgICAgIGlmIChjb3VudCAmIDEpCiAgICAgICAgICAgIHJlc3VsdCArPSBzdHJpbmc7CiAgICAgICAgaWYgKGNvdW50ID4+PSAxKQogICAgICAgICAgICBzdHJpbmcgKz0gc3RyaW5nOwogICAgfQogICAgcmV0dXJuIHJlc3VsdDsKfTsKdmFyIHRyaW1CZWdpblJlZ2V4cCA9IC9eXHNccyovOwp2YXIgdHJpbUVuZFJlZ2V4cCA9IC9cc1xzKiQvOwpleHBvcnRzLnN0cmluZ1RyaW1MZWZ0ID0gZnVuY3Rpb24gKHN0cmluZykgewogICAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKHRyaW1CZWdpblJlZ2V4cCwgJycpOwp9OwpleHBvcnRzLnN0cmluZ1RyaW1SaWdodCA9IGZ1bmN0aW9uIChzdHJpbmcpIHsKICAgIHJldHVybiBzdHJpbmcucmVwbGFjZSh0cmltRW5kUmVnZXhwLCAnJyk7Cn07CmV4cG9ydHMuY29weU9iamVjdCA9IGZ1bmN0aW9uIChvYmopIHsKICAgIHZhciBjb3B5ID0ge307CiAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7CiAgICAgICAgY29weVtrZXldID0gb2JqW2tleV07CiAgICB9CiAgICByZXR1cm4gY29weTsKfTsKZXhwb3J0cy5jb3B5QXJyYXkgPSBmdW5jdGlvbiAoYXJyYXkpIHsKICAgIHZhciBjb3B5ID0gW107CiAgICBmb3IgKHZhciBpID0gMCwgbCA9IGFycmF5Lmxlbmd0aDsgaSA8IGw7IGkrKykgewogICAgICAgIGlmIChhcnJheVtpXSAmJiB0eXBlb2YgYXJyYXlbaV0gPT0gIm9iamVjdCIpCiAgICAgICAgICAgIGNvcHlbaV0gPSB0aGlzLmNvcHlPYmplY3QoYXJyYXlbaV0pOwogICAgICAgIGVsc2UKICAgICAgICAgICAgY29weVtpXSA9IGFycmF5W2ldOwogICAgfQogICAgcmV0dXJuIGNvcHk7Cn07CmV4cG9ydHMuZGVlcENvcHkgPSByZXF1aXJlKCIuL2RlZXBfY29weSIpLmRlZXBDb3B5OwpleHBvcnRzLmFycmF5VG9NYXAgPSBmdW5jdGlvbiAoYXJyKSB7CiAgICB2YXIgbWFwID0ge307CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykgewogICAgICAgIG1hcFthcnJbaV1dID0gMTsKICAgIH0KICAgIHJldHVybiBtYXA7Cn07CmV4cG9ydHMuY3JlYXRlTWFwID0gZnVuY3Rpb24gKHByb3BzKSB7CiAgICB2YXIgbWFwID0gT2JqZWN0LmNyZWF0ZShudWxsKTsKICAgIGZvciAodmFyIGkgaW4gcHJvcHMpIHsKICAgICAgICBtYXBbaV0gPSBwcm9wc1tpXTsKICAgIH0KICAgIHJldHVybiBtYXA7Cn07CmV4cG9ydHMuYXJyYXlSZW1vdmUgPSBmdW5jdGlvbiAoYXJyYXksIHZhbHVlKSB7CiAgICBmb3IgKHZhciBpID0gMDsgaSA8PSBhcnJheS5sZW5ndGg7IGkrKykgewogICAgICAgIGlmICh2YWx1ZSA9PT0gYXJyYXlbaV0pIHsKICAgICAgICAgICAgYXJyYXkuc3BsaWNlKGksIDEpOwogICAgICAgIH0KICAgIH0KfTsKZXhwb3J0cy5lc2NhcGVSZWdFeHAgPSBmdW5jdGlvbiAoc3RyKSB7CiAgICByZXR1cm4gc3RyLnJlcGxhY2UoLyhbLiorP14ke30oKXxbXF1cL1xcXSkvZywgJ1xcJDEnKTsKfTsKZXhwb3J0cy5lc2NhcGVIVE1MID0gZnVuY3Rpb24gKHN0cikgewogICAgcmV0dXJuICgiIiArIHN0cikucmVwbGFjZSgvJi9nLCAiJiMzODsiKS5yZXBsYWNlKC8iL2csICImIzM0OyIpLnJlcGxhY2UoLycvZywgIiYjMzk7IikucmVwbGFjZSgvPC9nLCAiJiM2MDsiKTsKfTsKZXhwb3J0cy5nZXRNYXRjaE9mZnNldHMgPSBmdW5jdGlvbiAoc3RyaW5nLCByZWdFeHApIHsKICAgIHZhciBtYXRjaGVzID0gW107CiAgICBzdHJpbmcucmVwbGFjZShyZWdFeHAsIGZ1bmN0aW9uIChzdHIpIHsKICAgICAgICBtYXRjaGVzLnB1c2goewogICAgICAgICAgICBvZmZzZXQ6IGFyZ3VtZW50c1thcmd1bWVudHMubGVuZ3RoIC0gMl0sCiAgICAgICAgICAgIGxlbmd0aDogc3RyLmxlbmd0aAogICAgICAgIH0pOwogICAgfSk7CiAgICByZXR1cm4gbWF0Y2hlczsKfTsKZXhwb3J0cy5kZWZlcnJlZENhbGwgPSBmdW5jdGlvbiAoZmNuKSB7CiAgICB2YXIgdGltZXIgPSBudWxsOwogICAgdmFyIGNhbGxiYWNrID0gZnVuY3Rpb24gKCkgewogICAgICAgIHRpbWVyID0gbnVsbDsKICAgICAgICBmY24oKTsKICAgIH07CiAgICB2YXIgZGVmZXJyZWQgPSBmdW5jdGlvbiAodGltZW91dCkgewogICAgICAgIGRlZmVycmVkLmNhbmNlbCgpOwogICAgICAgIHRpbWVyID0gc2V0VGltZW91dChjYWxsYmFjaywgdGltZW91dCB8fCAwKTsKICAgICAgICByZXR1cm4gZGVmZXJyZWQ7CiAgICB9OwogICAgZGVmZXJyZWQuc2NoZWR1bGUgPSBkZWZlcnJlZDsKICAgIGRlZmVycmVkLmNhbGwgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdGhpcy5jYW5jZWwoKTsKICAgICAgICBmY24oKTsKICAgICAgICByZXR1cm4gZGVmZXJyZWQ7CiAgICB9OwogICAgZGVmZXJyZWQuY2FuY2VsID0gZnVuY3Rpb24gKCkgewogICAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7CiAgICAgICAgdGltZXIgPSBudWxsOwogICAgICAgIHJldHVybiBkZWZlcnJlZDsKICAgIH07CiAgICBkZWZlcnJlZC5pc1BlbmRpbmcgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgcmV0dXJuIHRpbWVyOwogICAgfTsKICAgIHJldHVybiBkZWZlcnJlZDsKfTsKZXhwb3J0cy5kZWxheWVkQ2FsbCA9IGZ1bmN0aW9uIChmY24sIGRlZmF1bHRUaW1lb3V0KSB7CiAgICB2YXIgdGltZXIgPSBudWxsOwogICAgdmFyIGNhbGxiYWNrID0gZnVuY3Rpb24gKCkgewogICAgICAgIHRpbWVyID0gbnVsbDsKICAgICAgICBmY24oKTsKICAgIH07CiAgICB2YXIgX3NlbGYgPSBmdW5jdGlvbiAodGltZW91dCkgewogICAgICAgIGlmICh0aW1lciA9PSBudWxsKQogICAgICAgICAgICB0aW1lciA9IHNldFRpbWVvdXQoY2FsbGJhY2ssIHRpbWVvdXQgfHwgZGVmYXVsdFRpbWVvdXQpOwogICAgfTsKICAgIF9zZWxmLmRlbGF5ID0gZnVuY3Rpb24gKHRpbWVvdXQpIHsKICAgICAgICB0aW1lciAmJiBjbGVhclRpbWVvdXQodGltZXIpOwogICAgICAgIHRpbWVyID0gc2V0VGltZW91dChjYWxsYmFjaywgdGltZW91dCB8fCBkZWZhdWx0VGltZW91dCk7CiAgICB9OwogICAgX3NlbGYuc2NoZWR1bGUgPSBfc2VsZjsKICAgIF9zZWxmLmNhbGwgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdGhpcy5jYW5jZWwoKTsKICAgICAgICBmY24oKTsKICAgIH07CiAgICBfc2VsZi5jYW5jZWwgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdGltZXIgJiYgY2xlYXJUaW1lb3V0KHRpbWVyKTsKICAgICAgICB0aW1lciA9IG51bGw7CiAgICB9OwogICAgX3NlbGYuaXNQZW5kaW5nID0gZnVuY3Rpb24gKCkgewogICAgICAgIHJldHVybiB0aW1lcjsKICAgIH07CiAgICByZXR1cm4gX3NlbGY7Cn07CmV4cG9ydHMuc2xlZXAgPSBmdW5jdGlvbiAobXMpIHsKICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkgewogICAgICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpOwogICAgfSk7Cn07CmV4cG9ydHMuc3VwcG9ydHNMb29rYmVoaW5kID0gZnVuY3Rpb24gKCkgewogICAgdHJ5IHsKICAgICAgICBuZXcgUmVnRXhwKCcoPzw9LiknKTsKICAgIH0KICAgIGNhdGNoIChlKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgcmV0dXJuIHRydWU7Cn07CmV4cG9ydHMuc2tpcEVtcHR5TWF0Y2ggPSBmdW5jdGlvbiAobGluZSwgbGFzdCwgc3VwcG9ydHNVbmljb2RlRmxhZykgewogICAgcmV0dXJuIHN1cHBvcnRzVW5pY29kZUZsYWcgJiYgbGluZS5jb2RlUG9pbnRBdChsYXN0KSA+IDB4ZmZmZiA/IDIgOiAxOwp9OwoKfSk7CgphY2UuZGVmaW5lKCJhY2Uvd29ya2VyL21pcnJvciIsW10sIGZ1bmN0aW9uKHJlcXVpcmUsIGV4cG9ydHMsIG1vZHVsZSkgewoidXNlIHN0cmljdCI7Cgp2YXIgRG9jdW1lbnQgPSByZXF1aXJlKCIuLi9kb2N1bWVudCIpLkRvY3VtZW50Owp2YXIgbGFuZyA9IHJlcXVpcmUoIi4uL2xpYi9sYW5nIik7CiAgICAKdmFyIE1pcnJvciA9IGV4cG9ydHMuTWlycm9yID0gZnVuY3Rpb24oc2VuZGVyKSB7CiAgICB0aGlzLnNlbmRlciA9IHNlbmRlcjsKICAgIHZhciBkb2MgPSB0aGlzLmRvYyA9IG5ldyBEb2N1bWVudCgiIik7CiAgICAKICAgIHZhciBkZWZlcnJlZFVwZGF0ZSA9IHRoaXMuZGVmZXJyZWRVcGRhdGUgPSBsYW5nLmRlbGF5ZWRDYWxsKHRoaXMub25VcGRhdGUuYmluZCh0aGlzKSk7CiAgICAKICAgIHZhciBfc2VsZiA9IHRoaXM7CiAgICBzZW5kZXIub24oImNoYW5nZSIsIGZ1bmN0aW9uKGUpIHsKICAgICAgICB2YXIgZGF0YSA9IGUuZGF0YTsKICAgICAgICBpZiAoZGF0YVswXS5zdGFydCkgewogICAgICAgICAgICBkb2MuYXBwbHlEZWx0YXMoZGF0YSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSArPSAyKSB7CiAgICAgICAgICAgICAgICB2YXIgZCwgZXJyOyAKICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGFbaSsxXSkpIHsKICAgICAgICAgICAgICAgICAgICBkID0ge2FjdGlvbjogImluc2VydCIsIHN0YXJ0OiBkYXRhW2ldLCBsaW5lczogZGF0YVtpKzFdfTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZCA9IHthY3Rpb246ICJyZW1vdmUiLCBzdGFydDogZGF0YVtpXSwgZW5kOiBkYXRhW2krMV19OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBpZiAoKGQuYWN0aW9uID09ICJpbnNlcnQiID8gZC5zdGFydCA6IGQuZW5kKS5yb3cgPj0gZG9jLiRsaW5lcy5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICBlcnIgPSBuZXcgRXJyb3IoIkludmFsaWQgZGVsdGEiKTsKICAgICAgICAgICAgICAgICAgICBlcnIuZGF0YSA9IHsKICAgICAgICAgICAgICAgICAgICAgICAgcGF0aDogX3NlbGYuJHBhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVzTGVuZ3RoOiBkb2MuJGxpbmVzLmxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnQ6IGQuc3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgIGVuZDogZC5lbmQKICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgIHRocm93IGVycjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBkb2MuYXBwbHlEZWx0YShkLCB0cnVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoX3NlbGYuJHRpbWVvdXQpCiAgICAgICAgICAgIHJldHVybiBkZWZlcnJlZFVwZGF0ZS5zY2hlZHVsZShfc2VsZi4kdGltZW91dCk7CiAgICAgICAgX3NlbGYub25VcGRhdGUoKTsKICAgIH0pOwp9OwoKKGZ1bmN0aW9uKCkgewogICAgCiAgICB0aGlzLiR0aW1lb3V0ID0gNTAwOwogICAgCiAgICB0aGlzLnNldFRpbWVvdXQgPSBmdW5jdGlvbih0aW1lb3V0KSB7CiAgICAgICAgdGhpcy4kdGltZW91dCA9IHRpbWVvdXQ7CiAgICB9OwogICAgCiAgICB0aGlzLnNldFZhbHVlID0gZnVuY3Rpb24odmFsdWUpIHsKICAgICAgICB0aGlzLmRvYy5zZXRWYWx1ZSh2YWx1ZSk7CiAgICAgICAgdGhpcy5kZWZlcnJlZFVwZGF0ZS5zY2hlZHVsZSh0aGlzLiR0aW1lb3V0KTsKICAgIH07CiAgICAKICAgIHRoaXMuZ2V0VmFsdWUgPSBmdW5jdGlvbihjYWxsYmFja0lkKSB7CiAgICAgICAgdGhpcy5zZW5kZXIuY2FsbGJhY2sodGhpcy5kb2MuZ2V0VmFsdWUoKSwgY2FsbGJhY2tJZCk7CiAgICB9OwogICAgCiAgICB0aGlzLm9uVXBkYXRlID0gZnVuY3Rpb24oKSB7CiAgICB9OwogICAgCiAgICB0aGlzLmlzUGVuZGluZyA9IGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiB0aGlzLmRlZmVycmVkVXBkYXRlLmlzUGVuZGluZygpOwogICAgfTsKICAgIAp9KS5jYWxsKE1pcnJvci5wcm90b3R5cGUpOwoKfSk7Cg=="), r.default.config.setModuleUrl("ace/mode/yaml_worker", "data:text/javascript;base64,Im5vIHVzZSBzdHJpY3QiOwohKGZ1bmN0aW9uKHdpbmRvdykgewppZiAodHlwZW9mIHdpbmRvdy53aW5kb3cgIT0gInVuZGVmaW5lZCIgJiYgd2luZG93LmRvY3VtZW50KQogICAgcmV0dXJuOwppZiAod2luZG93LnJlcXVpcmUgJiYgd2luZG93LmRlZmluZSkKICAgIHJldHVybjsKCmlmICghd2luZG93LmNvbnNvbGUpIHsKICAgIHdpbmRvdy5jb25zb2xlID0gZnVuY3Rpb24oKSB7CiAgICAgICAgdmFyIG1zZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApOwogICAgICAgIHBvc3RNZXNzYWdlKHt0eXBlOiAibG9nIiwgZGF0YTogbXNnc30pOwogICAgfTsKICAgIHdpbmRvdy5jb25zb2xlLmVycm9yID0KICAgIHdpbmRvdy5jb25zb2xlLndhcm4gPSAKICAgIHdpbmRvdy5jb25zb2xlLmxvZyA9CiAgICB3aW5kb3cuY29uc29sZS50cmFjZSA9IHdpbmRvdy5jb25zb2xlOwp9CndpbmRvdy53aW5kb3cgPSB3aW5kb3c7CndpbmRvdy5hY2UgPSB3aW5kb3c7Cgp3aW5kb3cub25lcnJvciA9IGZ1bmN0aW9uKG1lc3NhZ2UsIGZpbGUsIGxpbmUsIGNvbCwgZXJyKSB7CiAgICBwb3N0TWVzc2FnZSh7dHlwZTogImVycm9yIiwgZGF0YTogewogICAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsCiAgICAgICAgZGF0YTogZXJyICYmIGVyci5kYXRhLAogICAgICAgIGZpbGU6IGZpbGUsCiAgICAgICAgbGluZTogbGluZSwgCiAgICAgICAgY29sOiBjb2wsCiAgICAgICAgc3RhY2s6IGVyciAmJiBlcnIuc3RhY2sKICAgIH19KTsKfTsKCndpbmRvdy5ub3JtYWxpemVNb2R1bGUgPSBmdW5jdGlvbihwYXJlbnRJZCwgbW9kdWxlTmFtZSkgewogICAgLy8gbm9ybWFsaXplIHBsdWdpbiByZXF1aXJlcwogICAgaWYgKG1vZHVsZU5hbWUuaW5kZXhPZigiISIpICE9PSAtMSkgewogICAgICAgIHZhciBjaHVua3MgPSBtb2R1bGVOYW1lLnNwbGl0KCIhIik7CiAgICAgICAgcmV0dXJuIHdpbmRvdy5ub3JtYWxpemVNb2R1bGUocGFyZW50SWQsIGNodW5rc1swXSkgKyAiISIgKyB3aW5kb3cubm9ybWFsaXplTW9kdWxlKHBhcmVudElkLCBjaHVua3NbMV0pOwogICAgfQogICAgLy8gbm9ybWFsaXplIHJlbGF0aXZlIHJlcXVpcmVzCiAgICBpZiAobW9kdWxlTmFtZS5jaGFyQXQoMCkgPT0gIi4iKSB7CiAgICAgICAgdmFyIGJhc2UgPSBwYXJlbnRJZC5zcGxpdCgiLyIpLnNsaWNlKDAsIC0xKS5qb2luKCIvIik7CiAgICAgICAgbW9kdWxlTmFtZSA9IChiYXNlID8gYmFzZSArICIvIiA6ICIiKSArIG1vZHVsZU5hbWU7CiAgICAgICAgCiAgICAgICAgd2hpbGUgKG1vZHVsZU5hbWUuaW5kZXhPZigiLiIpICE9PSAtMSAmJiBwcmV2aW91cyAhPSBtb2R1bGVOYW1lKSB7CiAgICAgICAgICAgIHZhciBwcmV2aW91cyA9IG1vZHVsZU5hbWU7CiAgICAgICAgICAgIG1vZHVsZU5hbWUgPSBtb2R1bGVOYW1lLnJlcGxhY2UoL15cLlwvLywgIiIpLnJlcGxhY2UoL1wvXC5cLy8sICIvIikucmVwbGFjZSgvW15cL10rXC9cLlwuXC8vLCAiIik7CiAgICAgICAgfQogICAgfQogICAgCiAgICByZXR1cm4gbW9kdWxlTmFtZTsKfTsKCndpbmRvdy5yZXF1aXJlID0gZnVuY3Rpb24gcmVxdWlyZShwYXJlbnRJZCwgaWQpIHsKICAgIGlmICghaWQpIHsKICAgICAgICBpZCA9IHBhcmVudElkOwogICAgICAgIHBhcmVudElkID0gbnVsbDsKICAgIH0KICAgIGlmICghaWQuY2hhckF0KQogICAgICAgIHRocm93IG5ldyBFcnJvcigid29ya2VyLmpzIHJlcXVpcmUoKSBhY2NlcHRzIG9ubHkgKHBhcmVudElkLCBpZCkgYXMgYXJndW1lbnRzIik7CgogICAgaWQgPSB3aW5kb3cubm9ybWFsaXplTW9kdWxlKHBhcmVudElkLCBpZCk7CgogICAgdmFyIG1vZHVsZSA9IHdpbmRvdy5yZXF1aXJlLm1vZHVsZXNbaWRdOwogICAgaWYgKG1vZHVsZSkgewogICAgICAgIGlmICghbW9kdWxlLmluaXRpYWxpemVkKSB7CiAgICAgICAgICAgIG1vZHVsZS5pbml0aWFsaXplZCA9IHRydWU7CiAgICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gbW9kdWxlLmZhY3RvcnkoKS5leHBvcnRzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbW9kdWxlLmV4cG9ydHM7CiAgICB9CiAgIAogICAgaWYgKCF3aW5kb3cucmVxdWlyZS50bG5zKQogICAgICAgIHJldHVybiBjb25zb2xlLmxvZygidW5hYmxlIHRvIGxvYWQgIiArIGlkKTsKICAgIAogICAgdmFyIHBhdGggPSByZXNvbHZlTW9kdWxlSWQoaWQsIHdpbmRvdy5yZXF1aXJlLnRsbnMpOwogICAgaWYgKHBhdGguc2xpY2UoLTMpICE9ICIuanMiKSBwYXRoICs9ICIuanMiOwogICAgCiAgICB3aW5kb3cucmVxdWlyZS5pZCA9IGlkOwogICAgd2luZG93LnJlcXVpcmUubW9kdWxlc1tpZF0gPSB7fTsgLy8gcHJldmVudCBpbmZpbml0ZSBsb29wIG9uIGJyb2tlbiBtb2R1bGVzCiAgICBpbXBvcnRTY3JpcHRzKHBhdGgpOwogICAgcmV0dXJuIHdpbmRvdy5yZXF1aXJlKHBhcmVudElkLCBpZCk7Cn07CmZ1bmN0aW9uIHJlc29sdmVNb2R1bGVJZChpZCwgcGF0aHMpIHsKICAgIHZhciB0ZXN0UGF0aCA9IGlkLCB0YWlsID0gIiI7CiAgICB3aGlsZSAodGVzdFBhdGgpIHsKICAgICAgICB2YXIgYWxpYXMgPSBwYXRoc1t0ZXN0UGF0aF07CiAgICAgICAgaWYgKHR5cGVvZiBhbGlhcyA9PSAic3RyaW5nIikgewogICAgICAgICAgICByZXR1cm4gYWxpYXMgKyB0YWlsOwogICAgICAgIH0gZWxzZSBpZiAoYWxpYXMpIHsKICAgICAgICAgICAgcmV0dXJuICBhbGlhcy5sb2NhdGlvbi5yZXBsYWNlKC9cLyokLywgIi8iKSArICh0YWlsIHx8IGFsaWFzLm1haW4gfHwgYWxpYXMubmFtZSk7CiAgICAgICAgfSBlbHNlIGlmIChhbGlhcyA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgcmV0dXJuICIiOwogICAgICAgIH0KICAgICAgICB2YXIgaSA9IHRlc3RQYXRoLmxhc3RJbmRleE9mKCIvIik7CiAgICAgICAgaWYgKGkgPT09IC0xKSBicmVhazsKICAgICAgICB0YWlsID0gdGVzdFBhdGguc3Vic3RyKGkpICsgdGFpbDsKICAgICAgICB0ZXN0UGF0aCA9IHRlc3RQYXRoLnNsaWNlKDAsIGkpOwogICAgfQogICAgcmV0dXJuIGlkOwp9CndpbmRvdy5yZXF1aXJlLm1vZHVsZXMgPSB7fTsKd2luZG93LnJlcXVpcmUudGxucyA9IHt9OwoKd2luZG93LmRlZmluZSA9IGZ1bmN0aW9uKGlkLCBkZXBzLCBmYWN0b3J5KSB7CiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PSAyKSB7CiAgICAgICAgZmFjdG9yeSA9IGRlcHM7CiAgICAgICAgaWYgKHR5cGVvZiBpZCAhPSAic3RyaW5nIikgewogICAgICAgICAgICBkZXBzID0gaWQ7CiAgICAgICAgICAgIGlkID0gd2luZG93LnJlcXVpcmUuaWQ7CiAgICAgICAgfQogICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID09IDEpIHsKICAgICAgICBmYWN0b3J5ID0gaWQ7CiAgICAgICAgZGVwcyA9IFtdOwogICAgICAgIGlkID0gd2luZG93LnJlcXVpcmUuaWQ7CiAgICB9CiAgICAKICAgIGlmICh0eXBlb2YgZmFjdG9yeSAhPSAiZnVuY3Rpb24iKSB7CiAgICAgICAgd2luZG93LnJlcXVpcmUubW9kdWxlc1tpZF0gPSB7CiAgICAgICAgICAgIGV4cG9ydHM6IGZhY3RvcnksCiAgICAgICAgICAgIGluaXRpYWxpemVkOiB0cnVlCiAgICAgICAgfTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKCFkZXBzLmxlbmd0aCkKICAgICAgICAvLyBJZiB0aGVyZSBpcyBubyBkZXBlbmRlbmNpZXMsIHdlIGluamVjdCAicmVxdWlyZSIsICJleHBvcnRzIiBhbmQKICAgICAgICAvLyAibW9kdWxlIiBhcyBkZXBlbmRlbmNpZXMsIHRvIHByb3ZpZGUgQ29tbW9uSlMgY29tcGF0aWJpbGl0eS4KICAgICAgICBkZXBzID0gWyJyZXF1aXJlIiwgImV4cG9ydHMiLCAibW9kdWxlIl07CgogICAgdmFyIHJlcSA9IGZ1bmN0aW9uKGNoaWxkSWQpIHsKICAgICAgICByZXR1cm4gd2luZG93LnJlcXVpcmUoaWQsIGNoaWxkSWQpOwogICAgfTsKCiAgICB3aW5kb3cucmVxdWlyZS5tb2R1bGVzW2lkXSA9IHsKICAgICAgICBleHBvcnRzOiB7fSwKICAgICAgICBmYWN0b3J5OiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIG1vZHVsZSA9IHRoaXM7CiAgICAgICAgICAgIHZhciByZXR1cm5FeHBvcnRzID0gZmFjdG9yeS5hcHBseSh0aGlzLCBkZXBzLnNsaWNlKDAsIGZhY3RvcnkubGVuZ3RoKS5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKGRlcCkgewogICAgICAgICAgICAgICAgICAgIC8vIEJlY2F1c2UgInJlcXVpcmUiLCAiZXhwb3J0cyIgYW5kICJtb2R1bGUiIGFyZW4ndCBhY3R1YWwKICAgICAgICAgICAgICAgICAgICAvLyBkZXBlbmRlbmNpZXMsIHdlIG11c3QgaGFuZGxlIHRoZW0gc2VwZXJhdGVseS4KICAgICAgICAgICAgICAgICAgICBjYXNlICJyZXF1aXJlIjogcmV0dXJuIHJlcTsKICAgICAgICAgICAgICAgICAgICBjYXNlICJleHBvcnRzIjogcmV0dXJuIG1vZHVsZS5leHBvcnRzOwogICAgICAgICAgICAgICAgICAgIGNhc2UgIm1vZHVsZSI6ICByZXR1cm4gbW9kdWxlOwogICAgICAgICAgICAgICAgICAgIC8vIEJ1dCBmb3IgYWxsIG90aGVyIGRlcGVuZGVuY2llcywgd2UgY2FuIGp1c3QgZ28gYWhlYWQgYW5kCiAgICAgICAgICAgICAgICAgICAgLy8gcmVxdWlyZSB0aGVtLgogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6ICAgICAgICByZXR1cm4gcmVxKGRlcCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pKTsKICAgICAgICAgICAgaWYgKHJldHVybkV4cG9ydHMpCiAgICAgICAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IHJldHVybkV4cG9ydHM7CiAgICAgICAgICAgIHJldHVybiBtb2R1bGU7CiAgICAgICAgfQogICAgfTsKfTsKd2luZG93LmRlZmluZS5hbWQgPSB7fTsKd2luZG93LnJlcXVpcmUudGxucyA9IHt9Owp3aW5kb3cuaW5pdEJhc2VVcmxzICA9IGZ1bmN0aW9uIGluaXRCYXNlVXJscyh0b3BMZXZlbE5hbWVzcGFjZXMpIHsKICAgIGZvciAodmFyIGkgaW4gdG9wTGV2ZWxOYW1lc3BhY2VzKQogICAgICAgIHRoaXMucmVxdWlyZS50bG5zW2ldID0gdG9wTGV2ZWxOYW1lc3BhY2VzW2ldOwp9OwoKd2luZG93LmluaXRTZW5kZXIgPSBmdW5jdGlvbiBpbml0U2VuZGVyKCkgewoKICAgIHZhciBFdmVudEVtaXR0ZXIgPSB3aW5kb3cucmVxdWlyZSgiYWNlL2xpYi9ldmVudF9lbWl0dGVyIikuRXZlbnRFbWl0dGVyOwogICAgdmFyIG9vcCA9IHdpbmRvdy5yZXF1aXJlKCJhY2UvbGliL29vcCIpOwogICAgCiAgICB2YXIgU2VuZGVyID0gZnVuY3Rpb24oKSB7fTsKICAgIAogICAgKGZ1bmN0aW9uKCkgewogICAgICAgIAogICAgICAgIG9vcC5pbXBsZW1lbnQodGhpcywgRXZlbnRFbWl0dGVyKTsKICAgICAgICAgICAgICAgIAogICAgICAgIHRoaXMuY2FsbGJhY2sgPSBmdW5jdGlvbihkYXRhLCBjYWxsYmFja0lkKSB7CiAgICAgICAgICAgIHBvc3RNZXNzYWdlKHsKICAgICAgICAgICAgICAgIHR5cGU6ICJjYWxsIiwKICAgICAgICAgICAgICAgIGlkOiBjYWxsYmFja0lkLAogICAgICAgICAgICAgICAgZGF0YTogZGF0YQogICAgICAgICAgICB9KTsKICAgICAgICB9OwogICAgCiAgICAgICAgdGhpcy5lbWl0ID0gZnVuY3Rpb24obmFtZSwgZGF0YSkgewogICAgICAgICAgICBwb3N0TWVzc2FnZSh7CiAgICAgICAgICAgICAgICB0eXBlOiAiZXZlbnQiLAogICAgICAgICAgICAgICAgbmFtZTogbmFtZSwKICAgICAgICAgICAgICAgIGRhdGE6IGRhdGEKICAgICAgICAgICAgfSk7CiAgICAgICAgfTsKICAgICAgICAKICAgIH0pLmNhbGwoU2VuZGVyLnByb3RvdHlwZSk7CiAgICAKICAgIHJldHVybiBuZXcgU2VuZGVyKCk7Cn07Cgp2YXIgbWFpbiA9IHdpbmRvdy5tYWluID0gbnVsbDsKdmFyIHNlbmRlciA9IHdpbmRvdy5zZW5kZXIgPSBudWxsOwoKd2luZG93Lm9ubWVzc2FnZSA9IGZ1bmN0aW9uKGUpIHsKICAgIHZhciBtc2cgPSBlLmRhdGE7CiAgICBpZiAobXNnLmV2ZW50ICYmIHNlbmRlcikgewogICAgICAgIHNlbmRlci5fc2lnbmFsKG1zZy5ldmVudCwgbXNnLmRhdGEpOwogICAgfQogICAgZWxzZSBpZiAobXNnLmNvbW1hbmQpIHsKICAgICAgICBpZiAobWFpblttc2cuY29tbWFuZF0pCiAgICAgICAgICAgIG1haW5bbXNnLmNvbW1hbmRdLmFwcGx5KG1haW4sIG1zZy5hcmdzKTsKICAgICAgICBlbHNlIGlmICh3aW5kb3dbbXNnLmNvbW1hbmRdKQogICAgICAgICAgICB3aW5kb3dbbXNnLmNvbW1hbmRdLmFwcGx5KHdpbmRvdywgbXNnLmFyZ3MpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJVbmtub3duIGNvbW1hbmQ6IiArIG1zZy5jb21tYW5kKTsKICAgIH0KICAgIGVsc2UgaWYgKG1zZy5pbml0KSB7CiAgICAgICAgd2luZG93LmluaXRCYXNlVXJscyhtc2cudGxucyk7CiAgICAgICAgc2VuZGVyID0gd2luZG93LnNlbmRlciA9IHdpbmRvdy5pbml0U2VuZGVyKCk7CiAgICAgICAgdmFyIGNsYXp6ID0gdGhpcy5yZXF1aXJlKG1zZy5tb2R1bGUpW21zZy5jbGFzc25hbWVdOwogICAgICAgIG1haW4gPSB3aW5kb3cubWFpbiA9IG5ldyBjbGF6eihzZW5kZXIpOwogICAgfQp9Owp9KSh0aGlzKTsKCmFjZS5kZWZpbmUoImFjZS9saWIvb29wIixbXSwgZnVuY3Rpb24ocmVxdWlyZSwgZXhwb3J0cywgbW9kdWxlKXsidXNlIHN0cmljdCI7CmV4cG9ydHMuaW5oZXJpdHMgPSBmdW5jdGlvbiAoY3Rvciwgc3VwZXJDdG9yKSB7CiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvcjsKICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7CiAgICAgICAgY29uc3RydWN0b3I6IHsKICAgICAgICAgICAgdmFsdWU6IGN0b3IsCiAgICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLAogICAgICAgICAgICB3cml0YWJsZTogdHJ1ZSwKICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlCiAgICAgICAgfQogICAgfSk7Cn07CmV4cG9ydHMubWl4aW4gPSBmdW5jdGlvbiAob2JqLCBtaXhpbikgewogICAgZm9yICh2YXIga2V5IGluIG1peGluKSB7CiAgICAgICAgb2JqW2tleV0gPSBtaXhpbltrZXldOwogICAgfQogICAgcmV0dXJuIG9iajsKfTsKZXhwb3J0cy5pbXBsZW1lbnQgPSBmdW5jdGlvbiAocHJvdG8sIG1peGluKSB7CiAgICBleHBvcnRzLm1peGluKHByb3RvLCBtaXhpbik7Cn07Cgp9KTsKCmFjZS5kZWZpbmUoImFjZS9hcHBseV9kZWx0YSIsW10sIGZ1bmN0aW9uKHJlcXVpcmUsIGV4cG9ydHMsIG1vZHVsZSl7InVzZSBzdHJpY3QiOwpmdW5jdGlvbiB0aHJvd0RlbHRhRXJyb3IoZGVsdGEsIGVycm9yVGV4dCkgewogICAgY29uc29sZS5sb2coIkludmFsaWQgRGVsdGE6IiwgZGVsdGEpOwogICAgdGhyb3cgIkludmFsaWQgRGVsdGE6ICIgKyBlcnJvclRleHQ7Cn0KZnVuY3Rpb24gcG9zaXRpb25JbkRvY3VtZW50KGRvY0xpbmVzLCBwb3NpdGlvbikgewogICAgcmV0dXJuIHBvc2l0aW9uLnJvdyA+PSAwICYmIHBvc2l0aW9uLnJvdyA8IGRvY0xpbmVzLmxlbmd0aCAmJgogICAgICAgIHBvc2l0aW9uLmNvbHVtbiA+PSAwICYmIHBvc2l0aW9uLmNvbHVtbiA8PSBkb2NMaW5lc1twb3NpdGlvbi5yb3ddLmxlbmd0aDsKfQpmdW5jdGlvbiB2YWxpZGF0ZURlbHRhKGRvY0xpbmVzLCBkZWx0YSkgewogICAgaWYgKGRlbHRhLmFjdGlvbiAhPSAiaW5zZXJ0IiAmJiBkZWx0YS5hY3Rpb24gIT0gInJlbW92ZSIpCiAgICAgICAgdGhyb3dEZWx0YUVycm9yKGRlbHRhLCAiZGVsdGEuYWN0aW9uIG11c3QgYmUgJ2luc2VydCcgb3IgJ3JlbW92ZSciKTsKICAgIGlmICghKGRlbHRhLmxpbmVzIGluc3RhbmNlb2YgQXJyYXkpKQogICAgICAgIHRocm93RGVsdGFFcnJvcihkZWx0YSwgImRlbHRhLmxpbmVzIG11c3QgYmUgYW4gQXJyYXkiKTsKICAgIGlmICghZGVsdGEuc3RhcnQgfHwgIWRlbHRhLmVuZCkKICAgICAgICB0aHJvd0RlbHRhRXJyb3IoZGVsdGEsICJkZWx0YS5zdGFydC9lbmQgbXVzdCBiZSBhbiBwcmVzZW50Iik7CiAgICB2YXIgc3RhcnQgPSBkZWx0YS5zdGFydDsKICAgIGlmICghcG9zaXRpb25JbkRvY3VtZW50KGRvY0xpbmVzLCBkZWx0YS5zdGFydCkpCiAgICAgICAgdGhyb3dEZWx0YUVycm9yKGRlbHRhLCAiZGVsdGEuc3RhcnQgbXVzdCBiZSBjb250YWluZWQgaW4gZG9jdW1lbnQiKTsKICAgIHZhciBlbmQgPSBkZWx0YS5lbmQ7CiAgICBpZiAoZGVsdGEuYWN0aW9uID09ICJyZW1vdmUiICYmICFwb3NpdGlvbkluRG9jdW1lbnQoZG9jTGluZXMsIGVuZCkpCiAgICAgICAgdGhyb3dEZWx0YUVycm9yKGRlbHRhLCAiZGVsdGEuZW5kIG11c3QgY29udGFpbmVkIGluIGRvY3VtZW50IGZvciAncmVtb3ZlJyBhY3Rpb25zIik7CiAgICB2YXIgbnVtUmFuZ2VSb3dzID0gZW5kLnJvdyAtIHN0YXJ0LnJvdzsKICAgIHZhciBudW1SYW5nZUxhc3RMaW5lQ2hhcnMgPSAoZW5kLmNvbHVtbiAtIChudW1SYW5nZVJvd3MgPT0gMCA/IHN0YXJ0LmNvbHVtbiA6IDApKTsKICAgIGlmIChudW1SYW5nZVJvd3MgIT0gZGVsdGEubGluZXMubGVuZ3RoIC0gMSB8fCBkZWx0YS5saW5lc1tudW1SYW5nZVJvd3NdLmxlbmd0aCAhPSBudW1SYW5nZUxhc3RMaW5lQ2hhcnMpCiAgICAgICAgdGhyb3dEZWx0YUVycm9yKGRlbHRhLCAiZGVsdGEucmFuZ2UgbXVzdCBtYXRjaCBkZWx0YSBsaW5lcyIpOwp9CmV4cG9ydHMuYXBwbHlEZWx0YSA9IGZ1bmN0aW9uIChkb2NMaW5lcywgZGVsdGEsIGRvTm90VmFsaWRhdGUpIHsKICAgIHZhciByb3cgPSBkZWx0YS5zdGFydC5yb3c7CiAgICB2YXIgc3RhcnRDb2x1bW4gPSBkZWx0YS5zdGFydC5jb2x1bW47CiAgICB2YXIgbGluZSA9IGRvY0xpbmVzW3Jvd10gfHwgIiI7CiAgICBzd2l0Y2ggKGRlbHRhLmFjdGlvbikgewogICAgICAgIGNhc2UgImluc2VydCI6CiAgICAgICAgICAgIHZhciBsaW5lcyA9IGRlbHRhLmxpbmVzOwogICAgICAgICAgICBpZiAobGluZXMubGVuZ3RoID09PSAxKSB7CiAgICAgICAgICAgICAgICBkb2NMaW5lc1tyb3ddID0gbGluZS5zdWJzdHJpbmcoMCwgc3RhcnRDb2x1bW4pICsgZGVsdGEubGluZXNbMF0gKyBsaW5lLnN1YnN0cmluZyhzdGFydENvbHVtbik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICB2YXIgYXJncyA9IFtyb3csIDFdLmNvbmNhdChkZWx0YS5saW5lcyk7CiAgICAgICAgICAgICAgICBkb2NMaW5lcy5zcGxpY2UuYXBwbHkoZG9jTGluZXMsIGFyZ3MpOwogICAgICAgICAgICAgICAgZG9jTGluZXNbcm93XSA9IGxpbmUuc3Vic3RyaW5nKDAsIHN0YXJ0Q29sdW1uKSArIGRvY0xpbmVzW3Jvd107CiAgICAgICAgICAgICAgICBkb2NMaW5lc1tyb3cgKyBkZWx0YS5saW5lcy5sZW5ndGggLSAxXSArPSBsaW5lLnN1YnN0cmluZyhzdGFydENvbHVtbik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAicmVtb3ZlIjoKICAgICAgICAgICAgdmFyIGVuZENvbHVtbiA9IGRlbHRhLmVuZC5jb2x1bW47CiAgICAgICAgICAgIHZhciBlbmRSb3cgPSBkZWx0YS5lbmQucm93OwogICAgICAgICAgICBpZiAocm93ID09PSBlbmRSb3cpIHsKICAgICAgICAgICAgICAgIGRvY0xpbmVzW3Jvd10gPSBsaW5lLnN1YnN0cmluZygwLCBzdGFydENvbHVtbikgKyBsaW5lLnN1YnN0cmluZyhlbmRDb2x1bW4pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgZG9jTGluZXMuc3BsaWNlKHJvdywgZW5kUm93IC0gcm93ICsgMSwgbGluZS5zdWJzdHJpbmcoMCwgc3RhcnRDb2x1bW4pICsgZG9jTGluZXNbZW5kUm93XS5zdWJzdHJpbmcoZW5kQ29sdW1uKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICB9Cn07Cgp9KTsKCmFjZS5kZWZpbmUoImFjZS9saWIvZXZlbnRfZW1pdHRlciIsW10sIGZ1bmN0aW9uKHJlcXVpcmUsIGV4cG9ydHMsIG1vZHVsZSl7InVzZSBzdHJpY3QiOwp2YXIgRXZlbnRFbWl0dGVyID0ge307CnZhciBzdG9wUHJvcGFnYXRpb24gPSBmdW5jdGlvbiAoKSB7IHRoaXMucHJvcGFnYXRpb25TdG9wcGVkID0gdHJ1ZTsgfTsKdmFyIHByZXZlbnREZWZhdWx0ID0gZnVuY3Rpb24gKCkgeyB0aGlzLmRlZmF1bHRQcmV2ZW50ZWQgPSB0cnVlOyB9OwpFdmVudEVtaXR0ZXIuX2VtaXQgPQogICAgRXZlbnRFbWl0dGVyLl9kaXNwYXRjaEV2ZW50ID0gZnVuY3Rpb24gKGV2ZW50TmFtZSwgZSkgewogICAgICAgIHRoaXMuX2V2ZW50UmVnaXN0cnkgfHwgKHRoaXMuX2V2ZW50UmVnaXN0cnkgPSB7fSk7CiAgICAgICAgdGhpcy5fZGVmYXVsdEhhbmRsZXJzIHx8ICh0aGlzLl9kZWZhdWx0SGFuZGxlcnMgPSB7fSk7CiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuX2V2ZW50UmVnaXN0cnlbZXZlbnROYW1lXSB8fCBbXTsKICAgICAgICB2YXIgZGVmYXVsdEhhbmRsZXIgPSB0aGlzLl9kZWZhdWx0SGFuZGxlcnNbZXZlbnROYW1lXTsKICAgICAgICBpZiAoIWxpc3RlbmVycy5sZW5ndGggJiYgIWRlZmF1bHRIYW5kbGVyKQogICAgICAgICAgICByZXR1cm47CiAgICAgICAgaWYgKHR5cGVvZiBlICE9ICJvYmplY3QiIHx8ICFlKQogICAgICAgICAgICBlID0ge307CiAgICAgICAgaWYgKCFlLnR5cGUpCiAgICAgICAgICAgIGUudHlwZSA9IGV2ZW50TmFtZTsKICAgICAgICBpZiAoIWUuc3RvcFByb3BhZ2F0aW9uKQogICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbiA9IHN0b3BQcm9wYWdhdGlvbjsKICAgICAgICBpZiAoIWUucHJldmVudERlZmF1bHQpCiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQgPSBwcmV2ZW50RGVmYXVsdDsKICAgICAgICBsaXN0ZW5lcnMgPSBsaXN0ZW5lcnMuc2xpY2UoKTsKICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICBsaXN0ZW5lcnNbaV0oZSwgdGhpcyk7CiAgICAgICAgICAgIGlmIChlLnByb3BhZ2F0aW9uU3RvcHBlZCkKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBpZiAoZGVmYXVsdEhhbmRsZXIgJiYgIWUuZGVmYXVsdFByZXZlbnRlZCkKICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRIYW5kbGVyKGUsIHRoaXMpOwogICAgfTsKRXZlbnRFbWl0dGVyLl9zaWduYWwgPSBmdW5jdGlvbiAoZXZlbnROYW1lLCBlKSB7CiAgICB2YXIgbGlzdGVuZXJzID0gKHRoaXMuX2V2ZW50UmVnaXN0cnkgfHwge30pW2V2ZW50TmFtZV07CiAgICBpZiAoIWxpc3RlbmVycykKICAgICAgICByZXR1cm47CiAgICBsaXN0ZW5lcnMgPSBsaXN0ZW5lcnMuc2xpY2UoKTsKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDsgaSsrKQogICAgICAgIGxpc3RlbmVyc1tpXShlLCB0aGlzKTsKfTsKRXZlbnRFbWl0dGVyLm9uY2UgPSBmdW5jdGlvbiAoZXZlbnROYW1lLCBjYWxsYmFjaykgewogICAgdmFyIF9zZWxmID0gdGhpczsKICAgIHRoaXMub24oZXZlbnROYW1lLCBmdW5jdGlvbiBuZXdDYWxsYmFjaygpIHsKICAgICAgICBfc2VsZi5vZmYoZXZlbnROYW1lLCBuZXdDYWxsYmFjayk7CiAgICAgICAgY2FsbGJhY2suYXBwbHkobnVsbCwgYXJndW1lbnRzKTsKICAgIH0pOwogICAgaWYgKCFjYWxsYmFjaykgewogICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkgewogICAgICAgICAgICBjYWxsYmFjayA9IHJlc29sdmU7CiAgICAgICAgfSk7CiAgICB9Cn07CkV2ZW50RW1pdHRlci5zZXREZWZhdWx0SGFuZGxlciA9IGZ1bmN0aW9uIChldmVudE5hbWUsIGNhbGxiYWNrKSB7CiAgICB2YXIgaGFuZGxlcnMgPSB0aGlzLl9kZWZhdWx0SGFuZGxlcnM7CiAgICBpZiAoIWhhbmRsZXJzKQogICAgICAgIGhhbmRsZXJzID0gdGhpcy5fZGVmYXVsdEhhbmRsZXJzID0geyBfZGlzYWJsZWRfOiB7fSB9OwogICAgaWYgKGhhbmRsZXJzW2V2ZW50TmFtZV0pIHsKICAgICAgICB2YXIgb2xkID0gaGFuZGxlcnNbZXZlbnROYW1lXTsKICAgICAgICB2YXIgZGlzYWJsZWQgPSBoYW5kbGVycy5fZGlzYWJsZWRfW2V2ZW50TmFtZV07CiAgICAgICAgaWYgKCFkaXNhYmxlZCkKICAgICAgICAgICAgaGFuZGxlcnMuX2Rpc2FibGVkX1tldmVudE5hbWVdID0gZGlzYWJsZWQgPSBbXTsKICAgICAgICBkaXNhYmxlZC5wdXNoKG9sZCk7CiAgICAgICAgdmFyIGkgPSBkaXNhYmxlZC5pbmRleE9mKGNhbGxiYWNrKTsKICAgICAgICBpZiAoaSAhPSAtMSkKICAgICAgICAgICAgZGlzYWJsZWQuc3BsaWNlKGksIDEpOwogICAgfQogICAgaGFuZGxlcnNbZXZlbnROYW1lXSA9IGNhbGxiYWNrOwp9OwpFdmVudEVtaXR0ZXIucmVtb3ZlRGVmYXVsdEhhbmRsZXIgPSBmdW5jdGlvbiAoZXZlbnROYW1lLCBjYWxsYmFjaykgewogICAgdmFyIGhhbmRsZXJzID0gdGhpcy5fZGVmYXVsdEhhbmRsZXJzOwogICAgaWYgKCFoYW5kbGVycykKICAgICAgICByZXR1cm47CiAgICB2YXIgZGlzYWJsZWQgPSBoYW5kbGVycy5fZGlzYWJsZWRfW2V2ZW50TmFtZV07CiAgICBpZiAoaGFuZGxlcnNbZXZlbnROYW1lXSA9PSBjYWxsYmFjaykgewogICAgICAgIGlmIChkaXNhYmxlZCkKICAgICAgICAgICAgdGhpcy5zZXREZWZhdWx0SGFuZGxlcihldmVudE5hbWUsIGRpc2FibGVkLnBvcCgpKTsKICAgIH0KICAgIGVsc2UgaWYgKGRpc2FibGVkKSB7CiAgICAgICAgdmFyIGkgPSBkaXNhYmxlZC5pbmRleE9mKGNhbGxiYWNrKTsKICAgICAgICBpZiAoaSAhPSAtMSkKICAgICAgICAgICAgZGlzYWJsZWQuc3BsaWNlKGksIDEpOwogICAgfQp9OwpFdmVudEVtaXR0ZXIub24gPQogICAgRXZlbnRFbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbiAoZXZlbnROYW1lLCBjYWxsYmFjaywgY2FwdHVyaW5nKSB7CiAgICAgICAgdGhpcy5fZXZlbnRSZWdpc3RyeSA9IHRoaXMuX2V2ZW50UmVnaXN0cnkgfHwge307CiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuX2V2ZW50UmVnaXN0cnlbZXZlbnROYW1lXTsKICAgICAgICBpZiAoIWxpc3RlbmVycykKICAgICAgICAgICAgbGlzdGVuZXJzID0gdGhpcy5fZXZlbnRSZWdpc3RyeVtldmVudE5hbWVdID0gW107CiAgICAgICAgaWYgKGxpc3RlbmVycy5pbmRleE9mKGNhbGxiYWNrKSA9PSAtMSkKICAgICAgICAgICAgbGlzdGVuZXJzW2NhcHR1cmluZyA/ICJ1bnNoaWZ0IiA6ICJwdXNoIl0oY2FsbGJhY2spOwogICAgICAgIHJldHVybiBjYWxsYmFjazsKICAgIH07CkV2ZW50RW1pdHRlci5vZmYgPQogICAgRXZlbnRFbWl0dGVyLnJlbW92ZUxpc3RlbmVyID0KICAgICAgICBFdmVudEVtaXR0ZXIucmVtb3ZlRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uIChldmVudE5hbWUsIGNhbGxiYWNrKSB7CiAgICAgICAgICAgIHRoaXMuX2V2ZW50UmVnaXN0cnkgPSB0aGlzLl9ldmVudFJlZ2lzdHJ5IHx8IHt9OwogICAgICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5fZXZlbnRSZWdpc3RyeVtldmVudE5hbWVdOwogICAgICAgICAgICBpZiAoIWxpc3RlbmVycykKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgdmFyIGluZGV4ID0gbGlzdGVuZXJzLmluZGV4T2YoY2FsbGJhY2spOwogICAgICAgICAgICBpZiAoaW5kZXggIT09IC0xKQogICAgICAgICAgICAgICAgbGlzdGVuZXJzLnNwbGljZShpbmRleCwgMSk7CiAgICAgICAgfTsKRXZlbnRFbWl0dGVyLnJlbW92ZUFsbExpc3RlbmVycyA9IGZ1bmN0aW9uIChldmVudE5hbWUpIHsKICAgIGlmICghZXZlbnROYW1lKQogICAgICAgIHRoaXMuX2V2ZW50UmVnaXN0cnkgPSB0aGlzLl9kZWZhdWx0SGFuZGxlcnMgPSB1bmRlZmluZWQ7CiAgICBpZiAodGhpcy5fZXZlbnRSZWdpc3RyeSkKICAgICAgICB0aGlzLl9ldmVudFJlZ2lzdHJ5W2V2ZW50TmFtZV0gPSB1bmRlZmluZWQ7CiAgICBpZiAodGhpcy5fZGVmYXVsdEhhbmRsZXJzKQogICAgICAgIHRoaXMuX2RlZmF1bHRIYW5kbGVyc1tldmVudE5hbWVdID0gdW5kZWZpbmVkOwp9OwpleHBvcnRzLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjsKCn0pOwoKYWNlLmRlZmluZSgiYWNlL3JhbmdlIixbXSwgZnVuY3Rpb24ocmVxdWlyZSwgZXhwb3J0cywgbW9kdWxlKXsidXNlIHN0cmljdCI7CnZhciBSYW5nZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHsKICAgIGZ1bmN0aW9uIFJhbmdlKHN0YXJ0Um93LCBzdGFydENvbHVtbiwgZW5kUm93LCBlbmRDb2x1bW4pIHsKICAgICAgICB0aGlzLnN0YXJ0ID0gewogICAgICAgICAgICByb3c6IHN0YXJ0Um93LAogICAgICAgICAgICBjb2x1bW46IHN0YXJ0Q29sdW1uCiAgICAgICAgfTsKICAgICAgICB0aGlzLmVuZCA9IHsKICAgICAgICAgICAgcm93OiBlbmRSb3csCiAgICAgICAgICAgIGNvbHVtbjogZW5kQ29sdW1uCiAgICAgICAgfTsKICAgIH0KICAgIFJhbmdlLnByb3RvdHlwZS5pc0VxdWFsID0gZnVuY3Rpb24gKHJhbmdlKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuc3RhcnQucm93ID09PSByYW5nZS5zdGFydC5yb3cgJiYKICAgICAgICAgICAgdGhpcy5lbmQucm93ID09PSByYW5nZS5lbmQucm93ICYmCiAgICAgICAgICAgIHRoaXMuc3RhcnQuY29sdW1uID09PSByYW5nZS5zdGFydC5jb2x1bW4gJiYKICAgICAgICAgICAgdGhpcy5lbmQuY29sdW1uID09PSByYW5nZS5lbmQuY29sdW1uOwogICAgfTsKICAgIFJhbmdlLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHsKICAgICAgICByZXR1cm4gKCJSYW5nZTogWyIgKyB0aGlzLnN0YXJ0LnJvdyArICIvIiArIHRoaXMuc3RhcnQuY29sdW1uICsKICAgICAgICAgICAgIl0gLT4gWyIgKyB0aGlzLmVuZC5yb3cgKyAiLyIgKyB0aGlzLmVuZC5jb2x1bW4gKyAiXSIpOwogICAgfTsKICAgIFJhbmdlLnByb3RvdHlwZS5jb250YWlucyA9IGZ1bmN0aW9uIChyb3csIGNvbHVtbikgewogICAgICAgIHJldHVybiB0aGlzLmNvbXBhcmUocm93LCBjb2x1bW4pID09IDA7CiAgICB9OwogICAgUmFuZ2UucHJvdG90eXBlLmNvbXBhcmVSYW5nZSA9IGZ1bmN0aW9uIChyYW5nZSkgewogICAgICAgIHZhciBjbXAsIGVuZCA9IHJhbmdlLmVuZCwgc3RhcnQgPSByYW5nZS5zdGFydDsKICAgICAgICBjbXAgPSB0aGlzLmNvbXBhcmUoZW5kLnJvdywgZW5kLmNvbHVtbik7CiAgICAgICAgaWYgKGNtcCA9PSAxKSB7CiAgICAgICAgICAgIGNtcCA9IHRoaXMuY29tcGFyZShzdGFydC5yb3csIHN0YXJ0LmNvbHVtbik7CiAgICAgICAgICAgIGlmIChjbXAgPT0gMSkgewogICAgICAgICAgICAgICAgcmV0dXJuIDI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoY21wID09IDApIHsKICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoY21wID09IC0xKSB7CiAgICAgICAgICAgIHJldHVybiAtMjsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGNtcCA9IHRoaXMuY29tcGFyZShzdGFydC5yb3csIHN0YXJ0LmNvbHVtbik7CiAgICAgICAgICAgIGlmIChjbXAgPT0gLTEpIHsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChjbXAgPT0gMSkgewogICAgICAgICAgICAgICAgcmV0dXJuIDQyOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9OwogICAgUmFuZ2UucHJvdG90eXBlLmNvbXBhcmVQb2ludCA9IGZ1bmN0aW9uIChwKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuY29tcGFyZShwLnJvdywgcC5jb2x1bW4pOwogICAgfTsKICAgIFJhbmdlLnByb3RvdHlwZS5jb250YWluc1JhbmdlID0gZnVuY3Rpb24gKHJhbmdlKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuY29tcGFyZVBvaW50KHJhbmdlLnN0YXJ0KSA9PSAwICYmIHRoaXMuY29tcGFyZVBvaW50KHJhbmdlLmVuZCkgPT0gMDsKICAgIH07CiAgICBSYW5nZS5wcm90b3R5cGUuaW50ZXJzZWN0cyA9IGZ1bmN0aW9uIChyYW5nZSkgewogICAgICAgIHZhciBjbXAgPSB0aGlzLmNvbXBhcmVSYW5nZShyYW5nZSk7CiAgICAgICAgcmV0dXJuIChjbXAgPT0gLTEgfHwgY21wID09IDAgfHwgY21wID09IDEpOwogICAgfTsKICAgIFJhbmdlLnByb3RvdHlwZS5pc0VuZCA9IGZ1bmN0aW9uIChyb3csIGNvbHVtbikgewogICAgICAgIHJldHVybiB0aGlzLmVuZC5yb3cgPT0gcm93ICYmIHRoaXMuZW5kLmNvbHVtbiA9PSBjb2x1bW47CiAgICB9OwogICAgUmFuZ2UucHJvdG90eXBlLmlzU3RhcnQgPSBmdW5jdGlvbiAocm93LCBjb2x1bW4pIHsKICAgICAgICByZXR1cm4gdGhpcy5zdGFydC5yb3cgPT0gcm93ICYmIHRoaXMuc3RhcnQuY29sdW1uID09IGNvbHVtbjsKICAgIH07CiAgICBSYW5nZS5wcm90b3R5cGUuc2V0U3RhcnQgPSBmdW5jdGlvbiAocm93LCBjb2x1bW4pIHsKICAgICAgICBpZiAodHlwZW9mIHJvdyA9PSAib2JqZWN0IikgewogICAgICAgICAgICB0aGlzLnN0YXJ0LmNvbHVtbiA9IHJvdy5jb2x1bW47CiAgICAgICAgICAgIHRoaXMuc3RhcnQucm93ID0gcm93LnJvdzsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIHRoaXMuc3RhcnQucm93ID0gcm93OwogICAgICAgICAgICB0aGlzLnN0YXJ0LmNvbHVtbiA9IGNvbHVtbjsKICAgICAgICB9CiAgICB9OwogICAgUmFuZ2UucHJvdG90eXBlLnNldEVuZCA9IGZ1bmN0aW9uIChyb3csIGNvbHVtbikgewogICAgICAgIGlmICh0eXBlb2Ygcm93ID09ICJvYmplY3QiKSB7CiAgICAgICAgICAgIHRoaXMuZW5kLmNvbHVtbiA9IHJvdy5jb2x1bW47CiAgICAgICAgICAgIHRoaXMuZW5kLnJvdyA9IHJvdy5yb3c7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICB0aGlzLmVuZC5yb3cgPSByb3c7CiAgICAgICAgICAgIHRoaXMuZW5kLmNvbHVtbiA9IGNvbHVtbjsKICAgICAgICB9CiAgICB9OwogICAgUmFuZ2UucHJvdG90eXBlLmluc2lkZSA9IGZ1bmN0aW9uIChyb3csIGNvbHVtbikgewogICAgICAgIGlmICh0aGlzLmNvbXBhcmUocm93LCBjb2x1bW4pID09IDApIHsKICAgICAgICAgICAgaWYgKHRoaXMuaXNFbmQocm93LCBjb2x1bW4pIHx8IHRoaXMuaXNTdGFydChyb3csIGNvbHVtbikpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH07CiAgICBSYW5nZS5wcm90b3R5cGUuaW5zaWRlU3RhcnQgPSBmdW5jdGlvbiAocm93LCBjb2x1bW4pIHsKICAgICAgICBpZiAodGhpcy5jb21wYXJlKHJvdywgY29sdW1uKSA9PSAwKSB7CiAgICAgICAgICAgIGlmICh0aGlzLmlzRW5kKHJvdywgY29sdW1uKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfTsKICAgIFJhbmdlLnByb3RvdHlwZS5pbnNpZGVFbmQgPSBmdW5jdGlvbiAocm93LCBjb2x1bW4pIHsKICAgICAgICBpZiAodGhpcy5jb21wYXJlKHJvdywgY29sdW1uKSA9PSAwKSB7CiAgICAgICAgICAgIGlmICh0aGlzLmlzU3RhcnQocm93LCBjb2x1bW4pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9OwogICAgUmFuZ2UucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiAocm93LCBjb2x1bW4pIHsKICAgICAgICBpZiAoIXRoaXMuaXNNdWx0aUxpbmUoKSkgewogICAgICAgICAgICBpZiAocm93ID09PSB0aGlzLnN0YXJ0LnJvdykgewogICAgICAgICAgICAgICAgcmV0dXJuIGNvbHVtbiA8IHRoaXMuc3RhcnQuY29sdW1uID8gLTEgOiAoY29sdW1uID4gdGhpcy5lbmQuY29sdW1uID8gMSA6IDApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChyb3cgPCB0aGlzLnN0YXJ0LnJvdykKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIGlmIChyb3cgPiB0aGlzLmVuZC5yb3cpCiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIGlmICh0aGlzLnN0YXJ0LnJvdyA9PT0gcm93KQogICAgICAgICAgICByZXR1cm4gY29sdW1uID49IHRoaXMuc3RhcnQuY29sdW1uID8gMCA6IC0xOwogICAgICAgIGlmICh0aGlzLmVuZC5yb3cgPT09IHJvdykKICAgICAgICAgICAgcmV0dXJuIGNvbHVtbiA8PSB0aGlzLmVuZC5jb2x1bW4gPyAwIDogMTsKICAgICAgICByZXR1cm4gMDsKICAgIH07CiAgICBSYW5nZS5wcm90b3R5cGUuY29tcGFyZVN0YXJ0ID0gZnVuY3Rpb24gKHJvdywgY29sdW1uKSB7CiAgICAgICAgaWYgKHRoaXMuc3RhcnQucm93ID09IHJvdyAmJiB0aGlzLnN0YXJ0LmNvbHVtbiA9PSBjb2x1bW4pIHsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29tcGFyZShyb3csIGNvbHVtbik7CiAgICAgICAgfQogICAgfTsKICAgIFJhbmdlLnByb3RvdHlwZS5jb21wYXJlRW5kID0gZnVuY3Rpb24gKHJvdywgY29sdW1uKSB7CiAgICAgICAgaWYgKHRoaXMuZW5kLnJvdyA9PSByb3cgJiYgdGhpcy5lbmQuY29sdW1uID09IGNvbHVtbikgewogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbXBhcmUocm93LCBjb2x1bW4pOwogICAgICAgIH0KICAgIH07CiAgICBSYW5nZS5wcm90b3R5cGUuY29tcGFyZUluc2lkZSA9IGZ1bmN0aW9uIChyb3csIGNvbHVtbikgewogICAgICAgIGlmICh0aGlzLmVuZC5yb3cgPT0gcm93ICYmIHRoaXMuZW5kLmNvbHVtbiA9PSBjb2x1bW4pIHsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKHRoaXMuc3RhcnQucm93ID09IHJvdyAmJiB0aGlzLnN0YXJ0LmNvbHVtbiA9PSBjb2x1bW4pIHsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29tcGFyZShyb3csIGNvbHVtbik7CiAgICAgICAgfQogICAgfTsKICAgIFJhbmdlLnByb3RvdHlwZS5jbGlwUm93cyA9IGZ1bmN0aW9uIChmaXJzdFJvdywgbGFzdFJvdykgewogICAgICAgIGlmICh0aGlzLmVuZC5yb3cgPiBsYXN0Um93KQogICAgICAgICAgICB2YXIgZW5kID0geyByb3c6IGxhc3RSb3cgKyAxLCBjb2x1bW46IDAgfTsKICAgICAgICBlbHNlIGlmICh0aGlzLmVuZC5yb3cgPCBmaXJzdFJvdykKICAgICAgICAgICAgdmFyIGVuZCA9IHsgcm93OiBmaXJzdFJvdywgY29sdW1uOiAwIH07CiAgICAgICAgaWYgKHRoaXMuc3RhcnQucm93ID4gbGFzdFJvdykKICAgICAgICAgICAgdmFyIHN0YXJ0ID0geyByb3c6IGxhc3RSb3cgKyAxLCBjb2x1bW46IDAgfTsKICAgICAgICBlbHNlIGlmICh0aGlzLnN0YXJ0LnJvdyA8IGZpcnN0Um93KQogICAgICAgICAgICB2YXIgc3RhcnQgPSB7IHJvdzogZmlyc3RSb3csIGNvbHVtbjogMCB9OwogICAgICAgIHJldHVybiBSYW5nZS5mcm9tUG9pbnRzKHN0YXJ0IHx8IHRoaXMuc3RhcnQsIGVuZCB8fCB0aGlzLmVuZCk7CiAgICB9OwogICAgUmFuZ2UucHJvdG90eXBlLmV4dGVuZCA9IGZ1bmN0aW9uIChyb3csIGNvbHVtbikgewogICAgICAgIHZhciBjbXAgPSB0aGlzLmNvbXBhcmUocm93LCBjb2x1bW4pOwogICAgICAgIGlmIChjbXAgPT0gMCkKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgZWxzZSBpZiAoY21wID09IC0xKQogICAgICAgICAgICB2YXIgc3RhcnQgPSB7IHJvdzogcm93LCBjb2x1bW46IGNvbHVtbiB9OwogICAgICAgIGVsc2UKICAgICAgICAgICAgdmFyIGVuZCA9IHsgcm93OiByb3csIGNvbHVtbjogY29sdW1uIH07CiAgICAgICAgcmV0dXJuIFJhbmdlLmZyb21Qb2ludHMoc3RhcnQgfHwgdGhpcy5zdGFydCwgZW5kIHx8IHRoaXMuZW5kKTsKICAgIH07CiAgICBSYW5nZS5wcm90b3R5cGUuaXNFbXB0eSA9IGZ1bmN0aW9uICgpIHsKICAgICAgICByZXR1cm4gKHRoaXMuc3RhcnQucm93ID09PSB0aGlzLmVuZC5yb3cgJiYgdGhpcy5zdGFydC5jb2x1bW4gPT09IHRoaXMuZW5kLmNvbHVtbik7CiAgICB9OwogICAgUmFuZ2UucHJvdG90eXBlLmlzTXVsdGlMaW5lID0gZnVuY3Rpb24gKCkgewogICAgICAgIHJldHVybiAodGhpcy5zdGFydC5yb3cgIT09IHRoaXMuZW5kLnJvdyk7CiAgICB9OwogICAgUmFuZ2UucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24gKCkgewogICAgICAgIHJldHVybiBSYW5nZS5mcm9tUG9pbnRzKHRoaXMuc3RhcnQsIHRoaXMuZW5kKTsKICAgIH07CiAgICBSYW5nZS5wcm90b3R5cGUuY29sbGFwc2VSb3dzID0gZnVuY3Rpb24gKCkgewogICAgICAgIGlmICh0aGlzLmVuZC5jb2x1bW4gPT0gMCkKICAgICAgICAgICAgcmV0dXJuIG5ldyBSYW5nZSh0aGlzLnN0YXJ0LnJvdywgMCwgTWF0aC5tYXgodGhpcy5zdGFydC5yb3csIHRoaXMuZW5kLnJvdyAtIDEpLCAwKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHJldHVybiBuZXcgUmFuZ2UodGhpcy5zdGFydC5yb3csIDAsIHRoaXMuZW5kLnJvdywgMCk7CiAgICB9OwogICAgUmFuZ2UucHJvdG90eXBlLnRvU2NyZWVuUmFuZ2UgPSBmdW5jdGlvbiAoc2Vzc2lvbikgewogICAgICAgIHZhciBzY3JlZW5Qb3NTdGFydCA9IHNlc3Npb24uZG9jdW1lbnRUb1NjcmVlblBvc2l0aW9uKHRoaXMuc3RhcnQpOwogICAgICAgIHZhciBzY3JlZW5Qb3NFbmQgPSBzZXNzaW9uLmRvY3VtZW50VG9TY3JlZW5Qb3NpdGlvbih0aGlzLmVuZCk7CiAgICAgICAgcmV0dXJuIG5ldyBSYW5nZShzY3JlZW5Qb3NTdGFydC5yb3csIHNjcmVlblBvc1N0YXJ0LmNvbHVtbiwgc2NyZWVuUG9zRW5kLnJvdywgc2NyZWVuUG9zRW5kLmNvbHVtbik7CiAgICB9OwogICAgUmFuZ2UucHJvdG90eXBlLm1vdmVCeSA9IGZ1bmN0aW9uIChyb3csIGNvbHVtbikgewogICAgICAgIHRoaXMuc3RhcnQucm93ICs9IHJvdzsKICAgICAgICB0aGlzLnN0YXJ0LmNvbHVtbiArPSBjb2x1bW47CiAgICAgICAgdGhpcy5lbmQucm93ICs9IHJvdzsKICAgICAgICB0aGlzLmVuZC5jb2x1bW4gKz0gY29sdW1uOwogICAgfTsKICAgIHJldHVybiBSYW5nZTsKfSgpKTsKUmFuZ2UuZnJvbVBvaW50cyA9IGZ1bmN0aW9uIChzdGFydCwgZW5kKSB7CiAgICByZXR1cm4gbmV3IFJhbmdlKHN0YXJ0LnJvdywgc3RhcnQuY29sdW1uLCBlbmQucm93LCBlbmQuY29sdW1uKTsKfTsKUmFuZ2UuY29tcGFyZVBvaW50cyA9IGZ1bmN0aW9uIChwMSwgcDIpIHsKICAgIHJldHVybiBwMS5yb3cgLSBwMi5yb3cgfHwgcDEuY29sdW1uIC0gcDIuY29sdW1uOwp9OwpleHBvcnRzLlJhbmdlID0gUmFuZ2U7Cgp9KTsKCmFjZS5kZWZpbmUoImFjZS9hbmNob3IiLFtdLCBmdW5jdGlvbihyZXF1aXJlLCBleHBvcnRzLCBtb2R1bGUpeyJ1c2Ugc3RyaWN0IjsKdmFyIG9vcCA9IHJlcXVpcmUoIi4vbGliL29vcCIpOwp2YXIgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgiLi9saWIvZXZlbnRfZW1pdHRlciIpLkV2ZW50RW1pdHRlcjsKdmFyIEFuY2hvciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHsKICAgIGZ1bmN0aW9uIEFuY2hvcihkb2MsIHJvdywgY29sdW1uKSB7CiAgICAgICAgdGhpcy4kb25DaGFuZ2UgPSB0aGlzLm9uQ2hhbmdlLmJpbmQodGhpcyk7CiAgICAgICAgdGhpcy5hdHRhY2goZG9jKTsKICAgICAgICBpZiAodHlwZW9mIHJvdyAhPSAibnVtYmVyIikKICAgICAgICAgICAgdGhpcy5zZXRQb3NpdGlvbihyb3cucm93LCByb3cuY29sdW1uKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHRoaXMuc2V0UG9zaXRpb24ocm93LCBjb2x1bW4pOwogICAgfQogICAgQW5jaG9yLnByb3RvdHlwZS5nZXRQb3NpdGlvbiA9IGZ1bmN0aW9uICgpIHsKICAgICAgICByZXR1cm4gdGhpcy4kY2xpcFBvc2l0aW9uVG9Eb2N1bWVudCh0aGlzLnJvdywgdGhpcy5jb2x1bW4pOwogICAgfTsKICAgIEFuY2hvci5wcm90b3R5cGUuZ2V0RG9jdW1lbnQgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuZG9jdW1lbnQ7CiAgICB9OwogICAgQW5jaG9yLnByb3RvdHlwZS5vbkNoYW5nZSA9IGZ1bmN0aW9uIChkZWx0YSkgewogICAgICAgIGlmIChkZWx0YS5zdGFydC5yb3cgPT0gZGVsdGEuZW5kLnJvdyAmJiBkZWx0YS5zdGFydC5yb3cgIT0gdGhpcy5yb3cpCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICBpZiAoZGVsdGEuc3RhcnQucm93ID4gdGhpcy5yb3cpCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB2YXIgcG9pbnQgPSAkZ2V0VHJhbnNmb3JtZWRQb2ludChkZWx0YSwgeyByb3c6IHRoaXMucm93LCBjb2x1bW46IHRoaXMuY29sdW1uIH0sIHRoaXMuJGluc2VydFJpZ2h0KTsKICAgICAgICB0aGlzLnNldFBvc2l0aW9uKHBvaW50LnJvdywgcG9pbnQuY29sdW1uLCB0cnVlKTsKICAgIH07CiAgICBBbmNob3IucHJvdG90eXBlLnNldFBvc2l0aW9uID0gZnVuY3Rpb24gKHJvdywgY29sdW1uLCBub0NsaXApIHsKICAgICAgICB2YXIgcG9zOwogICAgICAgIGlmIChub0NsaXApIHsKICAgICAgICAgICAgcG9zID0gewogICAgICAgICAgICAgICAgcm93OiByb3csCiAgICAgICAgICAgICAgICBjb2x1bW46IGNvbHVtbgogICAgICAgICAgICB9OwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgcG9zID0gdGhpcy4kY2xpcFBvc2l0aW9uVG9Eb2N1bWVudChyb3csIGNvbHVtbik7CiAgICAgICAgfQogICAgICAgIGlmICh0aGlzLnJvdyA9PSBwb3Mucm93ICYmIHRoaXMuY29sdW1uID09IHBvcy5jb2x1bW4pCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB2YXIgb2xkID0gewogICAgICAgICAgICByb3c6IHRoaXMucm93LAogICAgICAgICAgICBjb2x1bW46IHRoaXMuY29sdW1uCiAgICAgICAgfTsKICAgICAgICB0aGlzLnJvdyA9IHBvcy5yb3c7CiAgICAgICAgdGhpcy5jb2x1bW4gPSBwb3MuY29sdW1uOwogICAgICAgIHRoaXMuX3NpZ25hbCgiY2hhbmdlIiwgewogICAgICAgICAgICBvbGQ6IG9sZCwKICAgICAgICAgICAgdmFsdWU6IHBvcwogICAgICAgIH0pOwogICAgfTsKICAgIEFuY2hvci5wcm90b3R5cGUuZGV0YWNoID0gZnVuY3Rpb24gKCkgewogICAgICAgIHRoaXMuZG9jdW1lbnQub2ZmKCJjaGFuZ2UiLCB0aGlzLiRvbkNoYW5nZSk7CiAgICB9OwogICAgQW5jaG9yLnByb3RvdHlwZS5hdHRhY2ggPSBmdW5jdGlvbiAoZG9jKSB7CiAgICAgICAgdGhpcy5kb2N1bWVudCA9IGRvYyB8fCB0aGlzLmRvY3VtZW50OwogICAgICAgIHRoaXMuZG9jdW1lbnQub24oImNoYW5nZSIsIHRoaXMuJG9uQ2hhbmdlKTsKICAgIH07CiAgICBBbmNob3IucHJvdG90eXBlLiRjbGlwUG9zaXRpb25Ub0RvY3VtZW50ID0gZnVuY3Rpb24gKHJvdywgY29sdW1uKSB7CiAgICAgICAgdmFyIHBvcyA9IHt9OwogICAgICAgIGlmIChyb3cgPj0gdGhpcy5kb2N1bWVudC5nZXRMZW5ndGgoKSkgewogICAgICAgICAgICBwb3Mucm93ID0gTWF0aC5tYXgoMCwgdGhpcy5kb2N1bWVudC5nZXRMZW5ndGgoKSAtIDEpOwogICAgICAgICAgICBwb3MuY29sdW1uID0gdGhpcy5kb2N1bWVudC5nZXRMaW5lKHBvcy5yb3cpLmxlbmd0aDsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAocm93IDwgMCkgewogICAgICAgICAgICBwb3Mucm93ID0gMDsKICAgICAgICAgICAgcG9zLmNvbHVtbiA9IDA7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBwb3Mucm93ID0gcm93OwogICAgICAgICAgICBwb3MuY29sdW1uID0gTWF0aC5taW4odGhpcy5kb2N1bWVudC5nZXRMaW5lKHBvcy5yb3cpLmxlbmd0aCwgTWF0aC5tYXgoMCwgY29sdW1uKSk7CiAgICAgICAgfQogICAgICAgIGlmIChjb2x1bW4gPCAwKQogICAgICAgICAgICBwb3MuY29sdW1uID0gMDsKICAgICAgICByZXR1cm4gcG9zOwogICAgfTsKICAgIHJldHVybiBBbmNob3I7Cn0oKSk7CkFuY2hvci5wcm90b3R5cGUuJGluc2VydFJpZ2h0ID0gZmFsc2U7Cm9vcC5pbXBsZW1lbnQoQW5jaG9yLnByb3RvdHlwZSwgRXZlbnRFbWl0dGVyKTsKZnVuY3Rpb24gJHBvaW50c0luT3JkZXIocG9pbnQxLCBwb2ludDIsIGVxdWFsUG9pbnRzSW5PcmRlcikgewogICAgdmFyIGJDb2xJc0FmdGVyID0gZXF1YWxQb2ludHNJbk9yZGVyID8gcG9pbnQxLmNvbHVtbiA8PSBwb2ludDIuY29sdW1uIDogcG9pbnQxLmNvbHVtbiA8IHBvaW50Mi5jb2x1bW47CiAgICByZXR1cm4gKHBvaW50MS5yb3cgPCBwb2ludDIucm93KSB8fCAocG9pbnQxLnJvdyA9PSBwb2ludDIucm93ICYmIGJDb2xJc0FmdGVyKTsKfQpmdW5jdGlvbiAkZ2V0VHJhbnNmb3JtZWRQb2ludChkZWx0YSwgcG9pbnQsIG1vdmVJZkVxdWFsKSB7CiAgICB2YXIgZGVsdGFJc0luc2VydCA9IGRlbHRhLmFjdGlvbiA9PSAiaW5zZXJ0IjsKICAgIHZhciBkZWx0YVJvd1NoaWZ0ID0gKGRlbHRhSXNJbnNlcnQgPyAxIDogLTEpICogKGRlbHRhLmVuZC5yb3cgLSBkZWx0YS5zdGFydC5yb3cpOwogICAgdmFyIGRlbHRhQ29sU2hpZnQgPSAoZGVsdGFJc0luc2VydCA/IDEgOiAtMSkgKiAoZGVsdGEuZW5kLmNvbHVtbiAtIGRlbHRhLnN0YXJ0LmNvbHVtbik7CiAgICB2YXIgZGVsdGFTdGFydCA9IGRlbHRhLnN0YXJ0OwogICAgdmFyIGRlbHRhRW5kID0gZGVsdGFJc0luc2VydCA/IGRlbHRhU3RhcnQgOiBkZWx0YS5lbmQ7IC8vIENvbGxhcHNlIGluc2VydCByYW5nZS4KICAgIGlmICgkcG9pbnRzSW5PcmRlcihwb2ludCwgZGVsdGFTdGFydCwgbW92ZUlmRXF1YWwpKSB7CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgcm93OiBwb2ludC5yb3csCiAgICAgICAgICAgIGNvbHVtbjogcG9pbnQuY29sdW1uCiAgICAgICAgfTsKICAgIH0KICAgIGlmICgkcG9pbnRzSW5PcmRlcihkZWx0YUVuZCwgcG9pbnQsICFtb3ZlSWZFcXVhbCkpIHsKICAgICAgICByZXR1cm4gewogICAgICAgICAgICByb3c6IHBvaW50LnJvdyArIGRlbHRhUm93U2hpZnQsCiAgICAgICAgICAgIGNvbHVtbjogcG9pbnQuY29sdW1uICsgKHBvaW50LnJvdyA9PSBkZWx0YUVuZC5yb3cgPyBkZWx0YUNvbFNoaWZ0IDogMCkKICAgICAgICB9OwogICAgfQogICAgcmV0dXJuIHsKICAgICAgICByb3c6IGRlbHRhU3RhcnQucm93LAogICAgICAgIGNvbHVtbjogZGVsdGFTdGFydC5jb2x1bW4KICAgIH07Cn0KZXhwb3J0cy5BbmNob3IgPSBBbmNob3I7Cgp9KTsKCmFjZS5kZWZpbmUoImFjZS9kb2N1bWVudCIsW10sIGZ1bmN0aW9uKHJlcXVpcmUsIGV4cG9ydHMsIG1vZHVsZSl7InVzZSBzdHJpY3QiOwp2YXIgb29wID0gcmVxdWlyZSgiLi9saWIvb29wIik7CnZhciBhcHBseURlbHRhID0gcmVxdWlyZSgiLi9hcHBseV9kZWx0YSIpLmFwcGx5RGVsdGE7CnZhciBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCIuL2xpYi9ldmVudF9lbWl0dGVyIikuRXZlbnRFbWl0dGVyOwp2YXIgUmFuZ2UgPSByZXF1aXJlKCIuL3JhbmdlIikuUmFuZ2U7CnZhciBBbmNob3IgPSByZXF1aXJlKCIuL2FuY2hvciIpLkFuY2hvcjsKdmFyIERvY3VtZW50ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkgewogICAgZnVuY3Rpb24gRG9jdW1lbnQodGV4dE9yTGluZXMpIHsKICAgICAgICB0aGlzLiRsaW5lcyA9IFsiIl07CiAgICAgICAgaWYgKHRleHRPckxpbmVzLmxlbmd0aCA9PT0gMCkgewogICAgICAgICAgICB0aGlzLiRsaW5lcyA9IFsiIl07CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKEFycmF5LmlzQXJyYXkodGV4dE9yTGluZXMpKSB7CiAgICAgICAgICAgIHRoaXMuaW5zZXJ0TWVyZ2VkTGluZXMoeyByb3c6IDAsIGNvbHVtbjogMCB9LCB0ZXh0T3JMaW5lcyk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICB0aGlzLmluc2VydCh7IHJvdzogMCwgY29sdW1uOiAwIH0sIHRleHRPckxpbmVzKTsKICAgICAgICB9CiAgICB9CiAgICBEb2N1bWVudC5wcm90b3R5cGUuc2V0VmFsdWUgPSBmdW5jdGlvbiAodGV4dCkgewogICAgICAgIHZhciBsZW4gPSB0aGlzLmdldExlbmd0aCgpIC0gMTsKICAgICAgICB0aGlzLnJlbW92ZShuZXcgUmFuZ2UoMCwgMCwgbGVuLCB0aGlzLmdldExpbmUobGVuKS5sZW5ndGgpKTsKICAgICAgICB0aGlzLmluc2VydCh7IHJvdzogMCwgY29sdW1uOiAwIH0sIHRleHQgfHwgIiIpOwogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS5nZXRWYWx1ZSA9IGZ1bmN0aW9uICgpIHsKICAgICAgICByZXR1cm4gdGhpcy5nZXRBbGxMaW5lcygpLmpvaW4odGhpcy5nZXROZXdMaW5lQ2hhcmFjdGVyKCkpOwogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS5jcmVhdGVBbmNob3IgPSBmdW5jdGlvbiAocm93LCBjb2x1bW4pIHsKICAgICAgICByZXR1cm4gbmV3IEFuY2hvcih0aGlzLCByb3csIGNvbHVtbik7CiAgICB9OwogICAgRG9jdW1lbnQucHJvdG90eXBlLiRkZXRlY3ROZXdMaW5lID0gZnVuY3Rpb24gKHRleHQpIHsKICAgICAgICB2YXIgbWF0Y2ggPSB0ZXh0Lm1hdGNoKC9eLio/KFxyXG58XHJ8XG4pL20pOwogICAgICAgIHRoaXMuJGF1dG9OZXdMaW5lID0gbWF0Y2ggPyBtYXRjaFsxXSA6ICJcbiI7CiAgICAgICAgdGhpcy5fc2lnbmFsKCJjaGFuZ2VOZXdMaW5lTW9kZSIpOwogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS5nZXROZXdMaW5lQ2hhcmFjdGVyID0gZnVuY3Rpb24gKCkgewogICAgICAgIHN3aXRjaCAodGhpcy4kbmV3TGluZU1vZGUpIHsKICAgICAgICAgICAgY2FzZSAid2luZG93cyI6CiAgICAgICAgICAgICAgICByZXR1cm4gIlxyXG4iOwogICAgICAgICAgICBjYXNlICJ1bml4IjoKICAgICAgICAgICAgICAgIHJldHVybiAiXG4iOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuJGF1dG9OZXdMaW5lIHx8ICJcbiI7CiAgICAgICAgfQogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS5zZXROZXdMaW5lTW9kZSA9IGZ1bmN0aW9uIChuZXdMaW5lTW9kZSkgewogICAgICAgIGlmICh0aGlzLiRuZXdMaW5lTW9kZSA9PT0gbmV3TGluZU1vZGUpCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB0aGlzLiRuZXdMaW5lTW9kZSA9IG5ld0xpbmVNb2RlOwogICAgICAgIHRoaXMuX3NpZ25hbCgiY2hhbmdlTmV3TGluZU1vZGUiKTsKICAgIH07CiAgICBEb2N1bWVudC5wcm90b3R5cGUuZ2V0TmV3TGluZU1vZGUgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuJG5ld0xpbmVNb2RlOwogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS5pc05ld0xpbmUgPSBmdW5jdGlvbiAodGV4dCkgewogICAgICAgIHJldHVybiAodGV4dCA9PSAiXHJcbiIgfHwgdGV4dCA9PSAiXHIiIHx8IHRleHQgPT0gIlxuIik7CiAgICB9OwogICAgRG9jdW1lbnQucHJvdG90eXBlLmdldExpbmUgPSBmdW5jdGlvbiAocm93KSB7CiAgICAgICAgcmV0dXJuIHRoaXMuJGxpbmVzW3Jvd10gfHwgIiI7CiAgICB9OwogICAgRG9jdW1lbnQucHJvdG90eXBlLmdldExpbmVzID0gZnVuY3Rpb24gKGZpcnN0Um93LCBsYXN0Um93KSB7CiAgICAgICAgcmV0dXJuIHRoaXMuJGxpbmVzLnNsaWNlKGZpcnN0Um93LCBsYXN0Um93ICsgMSk7CiAgICB9OwogICAgRG9jdW1lbnQucHJvdG90eXBlLmdldEFsbExpbmVzID0gZnVuY3Rpb24gKCkgewogICAgICAgIHJldHVybiB0aGlzLmdldExpbmVzKDAsIHRoaXMuZ2V0TGVuZ3RoKCkpOwogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS5nZXRMZW5ndGggPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuJGxpbmVzLmxlbmd0aDsKICAgIH07CiAgICBEb2N1bWVudC5wcm90b3R5cGUuZ2V0VGV4dFJhbmdlID0gZnVuY3Rpb24gKHJhbmdlKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0TGluZXNGb3JSYW5nZShyYW5nZSkuam9pbih0aGlzLmdldE5ld0xpbmVDaGFyYWN0ZXIoKSk7CiAgICB9OwogICAgRG9jdW1lbnQucHJvdG90eXBlLmdldExpbmVzRm9yUmFuZ2UgPSBmdW5jdGlvbiAocmFuZ2UpIHsKICAgICAgICB2YXIgbGluZXM7CiAgICAgICAgaWYgKHJhbmdlLnN0YXJ0LnJvdyA9PT0gcmFuZ2UuZW5kLnJvdykgewogICAgICAgICAgICBsaW5lcyA9IFt0aGlzLmdldExpbmUocmFuZ2Uuc3RhcnQucm93KS5zdWJzdHJpbmcocmFuZ2Uuc3RhcnQuY29sdW1uLCByYW5nZS5lbmQuY29sdW1uKV07CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBsaW5lcyA9IHRoaXMuZ2V0TGluZXMocmFuZ2Uuc3RhcnQucm93LCByYW5nZS5lbmQucm93KTsKICAgICAgICAgICAgbGluZXNbMF0gPSAobGluZXNbMF0gfHwgIiIpLnN1YnN0cmluZyhyYW5nZS5zdGFydC5jb2x1bW4pOwogICAgICAgICAgICB2YXIgbCA9IGxpbmVzLmxlbmd0aCAtIDE7CiAgICAgICAgICAgIGlmIChyYW5nZS5lbmQucm93IC0gcmFuZ2Uuc3RhcnQucm93ID09IGwpCiAgICAgICAgICAgICAgICBsaW5lc1tsXSA9IGxpbmVzW2xdLnN1YnN0cmluZygwLCByYW5nZS5lbmQuY29sdW1uKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGxpbmVzOwogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS5pbnNlcnRMaW5lcyA9IGZ1bmN0aW9uIChyb3csIGxpbmVzKSB7CiAgICAgICAgY29uc29sZS53YXJuKCJVc2Ugb2YgZG9jdW1lbnQuaW5zZXJ0TGluZXMgaXMgZGVwcmVjYXRlZC4gVXNlIHRoZSBpbnNlcnRGdWxsTGluZXMgbWV0aG9kIGluc3RlYWQuIik7CiAgICAgICAgcmV0dXJuIHRoaXMuaW5zZXJ0RnVsbExpbmVzKHJvdywgbGluZXMpOwogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS5yZW1vdmVMaW5lcyA9IGZ1bmN0aW9uIChmaXJzdFJvdywgbGFzdFJvdykgewogICAgICAgIGNvbnNvbGUud2FybigiVXNlIG9mIGRvY3VtZW50LnJlbW92ZUxpbmVzIGlzIGRlcHJlY2F0ZWQuIFVzZSB0aGUgcmVtb3ZlRnVsbExpbmVzIG1ldGhvZCBpbnN0ZWFkLiIpOwogICAgICAgIHJldHVybiB0aGlzLnJlbW92ZUZ1bGxMaW5lcyhmaXJzdFJvdywgbGFzdFJvdyk7CiAgICB9OwogICAgRG9jdW1lbnQucHJvdG90eXBlLmluc2VydE5ld0xpbmUgPSBmdW5jdGlvbiAocG9zaXRpb24pIHsKICAgICAgICBjb25zb2xlLndhcm4oIlVzZSBvZiBkb2N1bWVudC5pbnNlcnROZXdMaW5lIGlzIGRlcHJlY2F0ZWQuIFVzZSBpbnNlcnRNZXJnZWRMaW5lcyhwb3NpdGlvbiwgWycnLCAnJ10pIGluc3RlYWQuIik7CiAgICAgICAgcmV0dXJuIHRoaXMuaW5zZXJ0TWVyZ2VkTGluZXMocG9zaXRpb24sIFsiIiwgIiJdKTsKICAgIH07CiAgICBEb2N1bWVudC5wcm90b3R5cGUuaW5zZXJ0ID0gZnVuY3Rpb24gKHBvc2l0aW9uLCB0ZXh0KSB7CiAgICAgICAgaWYgKHRoaXMuZ2V0TGVuZ3RoKCkgPD0gMSkKICAgICAgICAgICAgdGhpcy4kZGV0ZWN0TmV3TGluZSh0ZXh0KTsKICAgICAgICByZXR1cm4gdGhpcy5pbnNlcnRNZXJnZWRMaW5lcyhwb3NpdGlvbiwgdGhpcy4kc3BsaXQodGV4dCkpOwogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS5pbnNlcnRJbkxpbmUgPSBmdW5jdGlvbiAocG9zaXRpb24sIHRleHQpIHsKICAgICAgICB2YXIgc3RhcnQgPSB0aGlzLmNsaXBwZWRQb3MocG9zaXRpb24ucm93LCBwb3NpdGlvbi5jb2x1bW4pOwogICAgICAgIHZhciBlbmQgPSB0aGlzLnBvcyhwb3NpdGlvbi5yb3csIHBvc2l0aW9uLmNvbHVtbiArIHRleHQubGVuZ3RoKTsKICAgICAgICB0aGlzLmFwcGx5RGVsdGEoewogICAgICAgICAgICBzdGFydDogc3RhcnQsCiAgICAgICAgICAgIGVuZDogZW5kLAogICAgICAgICAgICBhY3Rpb246ICJpbnNlcnQiLAogICAgICAgICAgICBsaW5lczogW3RleHRdCiAgICAgICAgfSwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIHRoaXMuY2xvbmVQb3MoZW5kKTsKICAgIH07CiAgICBEb2N1bWVudC5wcm90b3R5cGUuY2xpcHBlZFBvcyA9IGZ1bmN0aW9uIChyb3csIGNvbHVtbikgewogICAgICAgIHZhciBsZW5ndGggPSB0aGlzLmdldExlbmd0aCgpOwogICAgICAgIGlmIChyb3cgPT09IHVuZGVmaW5lZCkgewogICAgICAgICAgICByb3cgPSBsZW5ndGg7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKHJvdyA8IDApIHsKICAgICAgICAgICAgcm93ID0gMDsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAocm93ID49IGxlbmd0aCkgewogICAgICAgICAgICByb3cgPSBsZW5ndGggLSAxOwogICAgICAgICAgICBjb2x1bW4gPSB1bmRlZmluZWQ7CiAgICAgICAgfQogICAgICAgIHZhciBsaW5lID0gdGhpcy5nZXRMaW5lKHJvdyk7CiAgICAgICAgaWYgKGNvbHVtbiA9PSB1bmRlZmluZWQpCiAgICAgICAgICAgIGNvbHVtbiA9IGxpbmUubGVuZ3RoOwogICAgICAgIGNvbHVtbiA9IE1hdGgubWluKE1hdGgubWF4KGNvbHVtbiwgMCksIGxpbmUubGVuZ3RoKTsKICAgICAgICByZXR1cm4geyByb3c6IHJvdywgY29sdW1uOiBjb2x1bW4gfTsKICAgIH07CiAgICBEb2N1bWVudC5wcm90b3R5cGUuY2xvbmVQb3MgPSBmdW5jdGlvbiAocG9zKSB7CiAgICAgICAgcmV0dXJuIHsgcm93OiBwb3Mucm93LCBjb2x1bW46IHBvcy5jb2x1bW4gfTsKICAgIH07CiAgICBEb2N1bWVudC5wcm90b3R5cGUucG9zID0gZnVuY3Rpb24gKHJvdywgY29sdW1uKSB7CiAgICAgICAgcmV0dXJuIHsgcm93OiByb3csIGNvbHVtbjogY29sdW1uIH07CiAgICB9OwogICAgRG9jdW1lbnQucHJvdG90eXBlLiRjbGlwUG9zaXRpb24gPSBmdW5jdGlvbiAocG9zaXRpb24pIHsKICAgICAgICB2YXIgbGVuZ3RoID0gdGhpcy5nZXRMZW5ndGgoKTsKICAgICAgICBpZiAocG9zaXRpb24ucm93ID49IGxlbmd0aCkgewogICAgICAgICAgICBwb3NpdGlvbi5yb3cgPSBNYXRoLm1heCgwLCBsZW5ndGggLSAxKTsKICAgICAgICAgICAgcG9zaXRpb24uY29sdW1uID0gdGhpcy5nZXRMaW5lKGxlbmd0aCAtIDEpLmxlbmd0aDsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIHBvc2l0aW9uLnJvdyA9IE1hdGgubWF4KDAsIHBvc2l0aW9uLnJvdyk7CiAgICAgICAgICAgIHBvc2l0aW9uLmNvbHVtbiA9IE1hdGgubWluKE1hdGgubWF4KHBvc2l0aW9uLmNvbHVtbiwgMCksIHRoaXMuZ2V0TGluZShwb3NpdGlvbi5yb3cpLmxlbmd0aCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBwb3NpdGlvbjsKICAgIH07CiAgICBEb2N1bWVudC5wcm90b3R5cGUuaW5zZXJ0RnVsbExpbmVzID0gZnVuY3Rpb24gKHJvdywgbGluZXMpIHsKICAgICAgICByb3cgPSBNYXRoLm1pbihNYXRoLm1heChyb3csIDApLCB0aGlzLmdldExlbmd0aCgpKTsKICAgICAgICB2YXIgY29sdW1uID0gMDsKICAgICAgICBpZiAocm93IDwgdGhpcy5nZXRMZW5ndGgoKSkgewogICAgICAgICAgICBsaW5lcyA9IGxpbmVzLmNvbmNhdChbIiJdKTsKICAgICAgICAgICAgY29sdW1uID0gMDsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGxpbmVzID0gWyIiXS5jb25jYXQobGluZXMpOwogICAgICAgICAgICByb3ctLTsKICAgICAgICAgICAgY29sdW1uID0gdGhpcy4kbGluZXNbcm93XS5sZW5ndGg7CiAgICAgICAgfQogICAgICAgIHRoaXMuaW5zZXJ0TWVyZ2VkTGluZXMoeyByb3c6IHJvdywgY29sdW1uOiBjb2x1bW4gfSwgbGluZXMpOwogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS5pbnNlcnRNZXJnZWRMaW5lcyA9IGZ1bmN0aW9uIChwb3NpdGlvbiwgbGluZXMpIHsKICAgICAgICB2YXIgc3RhcnQgPSB0aGlzLmNsaXBwZWRQb3MocG9zaXRpb24ucm93LCBwb3NpdGlvbi5jb2x1bW4pOwogICAgICAgIHZhciBlbmQgPSB7CiAgICAgICAgICAgIHJvdzogc3RhcnQucm93ICsgbGluZXMubGVuZ3RoIC0gMSwKICAgICAgICAgICAgY29sdW1uOiAobGluZXMubGVuZ3RoID09IDEgPyBzdGFydC5jb2x1bW4gOiAwKSArIGxpbmVzW2xpbmVzLmxlbmd0aCAtIDFdLmxlbmd0aAogICAgICAgIH07CiAgICAgICAgdGhpcy5hcHBseURlbHRhKHsKICAgICAgICAgICAgc3RhcnQ6IHN0YXJ0LAogICAgICAgICAgICBlbmQ6IGVuZCwKICAgICAgICAgICAgYWN0aW9uOiAiaW5zZXJ0IiwKICAgICAgICAgICAgbGluZXM6IGxpbmVzCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIHRoaXMuY2xvbmVQb3MoZW5kKTsKICAgIH07CiAgICBEb2N1bWVudC5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24gKHJhbmdlKSB7CiAgICAgICAgdmFyIHN0YXJ0ID0gdGhpcy5jbGlwcGVkUG9zKHJhbmdlLnN0YXJ0LnJvdywgcmFuZ2Uuc3RhcnQuY29sdW1uKTsKICAgICAgICB2YXIgZW5kID0gdGhpcy5jbGlwcGVkUG9zKHJhbmdlLmVuZC5yb3csIHJhbmdlLmVuZC5jb2x1bW4pOwogICAgICAgIHRoaXMuYXBwbHlEZWx0YSh7CiAgICAgICAgICAgIHN0YXJ0OiBzdGFydCwKICAgICAgICAgICAgZW5kOiBlbmQsCiAgICAgICAgICAgIGFjdGlvbjogInJlbW92ZSIsCiAgICAgICAgICAgIGxpbmVzOiB0aGlzLmdldExpbmVzRm9yUmFuZ2UoeyBzdGFydDogc3RhcnQsIGVuZDogZW5kIH0pCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIHRoaXMuY2xvbmVQb3Moc3RhcnQpOwogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS5yZW1vdmVJbkxpbmUgPSBmdW5jdGlvbiAocm93LCBzdGFydENvbHVtbiwgZW5kQ29sdW1uKSB7CiAgICAgICAgdmFyIHN0YXJ0ID0gdGhpcy5jbGlwcGVkUG9zKHJvdywgc3RhcnRDb2x1bW4pOwogICAgICAgIHZhciBlbmQgPSB0aGlzLmNsaXBwZWRQb3Mocm93LCBlbmRDb2x1bW4pOwogICAgICAgIHRoaXMuYXBwbHlEZWx0YSh7CiAgICAgICAgICAgIHN0YXJ0OiBzdGFydCwKICAgICAgICAgICAgZW5kOiBlbmQsCiAgICAgICAgICAgIGFjdGlvbjogInJlbW92ZSIsCiAgICAgICAgICAgIGxpbmVzOiB0aGlzLmdldExpbmVzRm9yUmFuZ2UoeyBzdGFydDogc3RhcnQsIGVuZDogZW5kIH0pCiAgICAgICAgfSwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIHRoaXMuY2xvbmVQb3Moc3RhcnQpOwogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS5yZW1vdmVGdWxsTGluZXMgPSBmdW5jdGlvbiAoZmlyc3RSb3csIGxhc3RSb3cpIHsKICAgICAgICBmaXJzdFJvdyA9IE1hdGgubWluKE1hdGgubWF4KDAsIGZpcnN0Um93KSwgdGhpcy5nZXRMZW5ndGgoKSAtIDEpOwogICAgICAgIGxhc3RSb3cgPSBNYXRoLm1pbihNYXRoLm1heCgwLCBsYXN0Um93KSwgdGhpcy5nZXRMZW5ndGgoKSAtIDEpOwogICAgICAgIHZhciBkZWxldGVGaXJzdE5ld0xpbmUgPSBsYXN0Um93ID09IHRoaXMuZ2V0TGVuZ3RoKCkgLSAxICYmIGZpcnN0Um93ID4gMDsKICAgICAgICB2YXIgZGVsZXRlTGFzdE5ld0xpbmUgPSBsYXN0Um93IDwgdGhpcy5nZXRMZW5ndGgoKSAtIDE7CiAgICAgICAgdmFyIHN0YXJ0Um93ID0gKGRlbGV0ZUZpcnN0TmV3TGluZSA/IGZpcnN0Um93IC0gMSA6IGZpcnN0Um93KTsKICAgICAgICB2YXIgc3RhcnRDb2wgPSAoZGVsZXRlRmlyc3ROZXdMaW5lID8gdGhpcy5nZXRMaW5lKHN0YXJ0Um93KS5sZW5ndGggOiAwKTsKICAgICAgICB2YXIgZW5kUm93ID0gKGRlbGV0ZUxhc3ROZXdMaW5lID8gbGFzdFJvdyArIDEgOiBsYXN0Um93KTsKICAgICAgICB2YXIgZW5kQ29sID0gKGRlbGV0ZUxhc3ROZXdMaW5lID8gMCA6IHRoaXMuZ2V0TGluZShlbmRSb3cpLmxlbmd0aCk7CiAgICAgICAgdmFyIHJhbmdlID0gbmV3IFJhbmdlKHN0YXJ0Um93LCBzdGFydENvbCwgZW5kUm93LCBlbmRDb2wpOwogICAgICAgIHZhciBkZWxldGVkTGluZXMgPSB0aGlzLiRsaW5lcy5zbGljZShmaXJzdFJvdywgbGFzdFJvdyArIDEpOwogICAgICAgIHRoaXMuYXBwbHlEZWx0YSh7CiAgICAgICAgICAgIHN0YXJ0OiByYW5nZS5zdGFydCwKICAgICAgICAgICAgZW5kOiByYW5nZS5lbmQsCiAgICAgICAgICAgIGFjdGlvbjogInJlbW92ZSIsCiAgICAgICAgICAgIGxpbmVzOiB0aGlzLmdldExpbmVzRm9yUmFuZ2UocmFuZ2UpCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIGRlbGV0ZWRMaW5lczsKICAgIH07CiAgICBEb2N1bWVudC5wcm90b3R5cGUucmVtb3ZlTmV3TGluZSA9IGZ1bmN0aW9uIChyb3cpIHsKICAgICAgICBpZiAocm93IDwgdGhpcy5nZXRMZW5ndGgoKSAtIDEgJiYgcm93ID49IDApIHsKICAgICAgICAgICAgdGhpcy5hcHBseURlbHRhKHsKICAgICAgICAgICAgICAgIHN0YXJ0OiB0aGlzLnBvcyhyb3csIHRoaXMuZ2V0TGluZShyb3cpLmxlbmd0aCksCiAgICAgICAgICAgICAgICBlbmQ6IHRoaXMucG9zKHJvdyArIDEsIDApLAogICAgICAgICAgICAgICAgYWN0aW9uOiAicmVtb3ZlIiwKICAgICAgICAgICAgICAgIGxpbmVzOiBbIiIsICIiXQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9OwogICAgRG9jdW1lbnQucHJvdG90eXBlLnJlcGxhY2UgPSBmdW5jdGlvbiAocmFuZ2UsIHRleHQpIHsKICAgICAgICBpZiAoIShyYW5nZSBpbnN0YW5jZW9mIFJhbmdlKSkKICAgICAgICAgICAgcmFuZ2UgPSBSYW5nZS5mcm9tUG9pbnRzKHJhbmdlLnN0YXJ0LCByYW5nZS5lbmQpOwogICAgICAgIGlmICh0ZXh0Lmxlbmd0aCA9PT0gMCAmJiByYW5nZS5pc0VtcHR5KCkpCiAgICAgICAgICAgIHJldHVybiByYW5nZS5zdGFydDsKICAgICAgICBpZiAodGV4dCA9PSB0aGlzLmdldFRleHRSYW5nZShyYW5nZSkpCiAgICAgICAgICAgIHJldHVybiByYW5nZS5lbmQ7CiAgICAgICAgdGhpcy5yZW1vdmUocmFuZ2UpOwogICAgICAgIHZhciBlbmQ7CiAgICAgICAgaWYgKHRleHQpIHsKICAgICAgICAgICAgZW5kID0gdGhpcy5pbnNlcnQocmFuZ2Uuc3RhcnQsIHRleHQpOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgZW5kID0gcmFuZ2Uuc3RhcnQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiBlbmQ7CiAgICB9OwogICAgRG9jdW1lbnQucHJvdG90eXBlLmFwcGx5RGVsdGFzID0gZnVuY3Rpb24gKGRlbHRhcykgewogICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGVsdGFzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHRoaXMuYXBwbHlEZWx0YShkZWx0YXNbaV0pOwogICAgICAgIH0KICAgIH07CiAgICBEb2N1bWVudC5wcm90b3R5cGUucmV2ZXJ0RGVsdGFzID0gZnVuY3Rpb24gKGRlbHRhcykgewogICAgICAgIGZvciAodmFyIGkgPSBkZWx0YXMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHsKICAgICAgICAgICAgdGhpcy5yZXZlcnREZWx0YShkZWx0YXNbaV0pOwogICAgICAgIH0KICAgIH07CiAgICBEb2N1bWVudC5wcm90b3R5cGUuYXBwbHlEZWx0YSA9IGZ1bmN0aW9uIChkZWx0YSwgZG9Ob3RWYWxpZGF0ZSkgewogICAgICAgIHZhciBpc0luc2VydCA9IGRlbHRhLmFjdGlvbiA9PSAiaW5zZXJ0IjsKICAgICAgICBpZiAoaXNJbnNlcnQgPyBkZWx0YS5saW5lcy5sZW5ndGggPD0gMSAmJiAhZGVsdGEubGluZXNbMF0KICAgICAgICAgICAgOiAhUmFuZ2UuY29tcGFyZVBvaW50cyhkZWx0YS5zdGFydCwgZGVsdGEuZW5kKSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGlmIChpc0luc2VydCAmJiBkZWx0YS5saW5lcy5sZW5ndGggPiAyMDAwMCkgewogICAgICAgICAgICB0aGlzLiRzcGxpdEFuZGFwcGx5TGFyZ2VEZWx0YShkZWx0YSwgMjAwMDApOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgYXBwbHlEZWx0YSh0aGlzLiRsaW5lcywgZGVsdGEsIGRvTm90VmFsaWRhdGUpOwogICAgICAgICAgICB0aGlzLl9zaWduYWwoImNoYW5nZSIsIGRlbHRhKTsKICAgICAgICB9CiAgICB9OwogICAgRG9jdW1lbnQucHJvdG90eXBlLiRzYWZlQXBwbHlEZWx0YSA9IGZ1bmN0aW9uIChkZWx0YSkgewogICAgICAgIHZhciBkb2NMZW5ndGggPSB0aGlzLiRsaW5lcy5sZW5ndGg7CiAgICAgICAgaWYgKGRlbHRhLmFjdGlvbiA9PSAicmVtb3ZlIiAmJiBkZWx0YS5zdGFydC5yb3cgPCBkb2NMZW5ndGggJiYgZGVsdGEuZW5kLnJvdyA8IGRvY0xlbmd0aAogICAgICAgICAgICB8fCBkZWx0YS5hY3Rpb24gPT0gImluc2VydCIgJiYgZGVsdGEuc3RhcnQucm93IDw9IGRvY0xlbmd0aCkgewogICAgICAgICAgICB0aGlzLmFwcGx5RGVsdGEoZGVsdGEpOwogICAgICAgIH0KICAgIH07CiAgICBEb2N1bWVudC5wcm90b3R5cGUuJHNwbGl0QW5kYXBwbHlMYXJnZURlbHRhID0gZnVuY3Rpb24gKGRlbHRhLCBNQVgpIHsKICAgICAgICB2YXIgbGluZXMgPSBkZWx0YS5saW5lczsKICAgICAgICB2YXIgbCA9IGxpbmVzLmxlbmd0aCAtIE1BWCArIDE7CiAgICAgICAgdmFyIHJvdyA9IGRlbHRhLnN0YXJ0LnJvdzsKICAgICAgICB2YXIgY29sdW1uID0gZGVsdGEuc3RhcnQuY29sdW1uOwogICAgICAgIGZvciAodmFyIGZyb20gPSAwLCB0byA9IDA7IGZyb20gPCBsOyBmcm9tID0gdG8pIHsKICAgICAgICAgICAgdG8gKz0gTUFYIC0gMTsKICAgICAgICAgICAgdmFyIGNodW5rID0gbGluZXMuc2xpY2UoZnJvbSwgdG8pOwogICAgICAgICAgICBjaHVuay5wdXNoKCIiKTsKICAgICAgICAgICAgdGhpcy5hcHBseURlbHRhKHsKICAgICAgICAgICAgICAgIHN0YXJ0OiB0aGlzLnBvcyhyb3cgKyBmcm9tLCBjb2x1bW4pLAogICAgICAgICAgICAgICAgZW5kOiB0aGlzLnBvcyhyb3cgKyB0bywgY29sdW1uID0gMCksCiAgICAgICAgICAgICAgICBhY3Rpb246IGRlbHRhLmFjdGlvbiwKICAgICAgICAgICAgICAgIGxpbmVzOiBjaHVuawogICAgICAgICAgICB9LCB0cnVlKTsKICAgICAgICB9CiAgICAgICAgZGVsdGEubGluZXMgPSBsaW5lcy5zbGljZShmcm9tKTsKICAgICAgICBkZWx0YS5zdGFydC5yb3cgPSByb3cgKyBmcm9tOwogICAgICAgIGRlbHRhLnN0YXJ0LmNvbHVtbiA9IGNvbHVtbjsKICAgICAgICB0aGlzLmFwcGx5RGVsdGEoZGVsdGEsIHRydWUpOwogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS5yZXZlcnREZWx0YSA9IGZ1bmN0aW9uIChkZWx0YSkgewogICAgICAgIHRoaXMuJHNhZmVBcHBseURlbHRhKHsKICAgICAgICAgICAgc3RhcnQ6IHRoaXMuY2xvbmVQb3MoZGVsdGEuc3RhcnQpLAogICAgICAgICAgICBlbmQ6IHRoaXMuY2xvbmVQb3MoZGVsdGEuZW5kKSwKICAgICAgICAgICAgYWN0aW9uOiAoZGVsdGEuYWN0aW9uID09ICJpbnNlcnQiID8gInJlbW92ZSIgOiAiaW5zZXJ0IiksCiAgICAgICAgICAgIGxpbmVzOiBkZWx0YS5saW5lcy5zbGljZSgpCiAgICAgICAgfSk7CiAgICB9OwogICAgRG9jdW1lbnQucHJvdG90eXBlLmluZGV4VG9Qb3NpdGlvbiA9IGZ1bmN0aW9uIChpbmRleCwgc3RhcnRSb3cpIHsKICAgICAgICB2YXIgbGluZXMgPSB0aGlzLiRsaW5lcyB8fCB0aGlzLmdldEFsbExpbmVzKCk7CiAgICAgICAgdmFyIG5ld2xpbmVMZW5ndGggPSB0aGlzLmdldE5ld0xpbmVDaGFyYWN0ZXIoKS5sZW5ndGg7CiAgICAgICAgZm9yICh2YXIgaSA9IHN0YXJ0Um93IHx8IDAsIGwgPSBsaW5lcy5sZW5ndGg7IGkgPCBsOyBpKyspIHsKICAgICAgICAgICAgaW5kZXggLT0gbGluZXNbaV0ubGVuZ3RoICsgbmV3bGluZUxlbmd0aDsKICAgICAgICAgICAgaWYgKGluZGV4IDwgMCkKICAgICAgICAgICAgICAgIHJldHVybiB7IHJvdzogaSwgY29sdW1uOiBpbmRleCArIGxpbmVzW2ldLmxlbmd0aCArIG5ld2xpbmVMZW5ndGggfTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHsgcm93OiBsIC0gMSwgY29sdW1uOiBpbmRleCArIGxpbmVzW2wgLSAxXS5sZW5ndGggKyBuZXdsaW5lTGVuZ3RoIH07CiAgICB9OwogICAgRG9jdW1lbnQucHJvdG90eXBlLnBvc2l0aW9uVG9JbmRleCA9IGZ1bmN0aW9uIChwb3MsIHN0YXJ0Um93KSB7CiAgICAgICAgdmFyIGxpbmVzID0gdGhpcy4kbGluZXMgfHwgdGhpcy5nZXRBbGxMaW5lcygpOwogICAgICAgIHZhciBuZXdsaW5lTGVuZ3RoID0gdGhpcy5nZXROZXdMaW5lQ2hhcmFjdGVyKCkubGVuZ3RoOwogICAgICAgIHZhciBpbmRleCA9IDA7CiAgICAgICAgdmFyIHJvdyA9IE1hdGgubWluKHBvcy5yb3csIGxpbmVzLmxlbmd0aCk7CiAgICAgICAgZm9yICh2YXIgaSA9IHN0YXJ0Um93IHx8IDA7IGkgPCByb3c7ICsraSkKICAgICAgICAgICAgaW5kZXggKz0gbGluZXNbaV0ubGVuZ3RoICsgbmV3bGluZUxlbmd0aDsKICAgICAgICByZXR1cm4gaW5kZXggKyBwb3MuY29sdW1uOwogICAgfTsKICAgIERvY3VtZW50LnByb3RvdHlwZS4kc3BsaXQgPSBmdW5jdGlvbiAodGV4dCkgewogICAgICAgIHJldHVybiB0ZXh0LnNwbGl0KC9cclxufFxyfFxuLyk7CiAgICB9OwogICAgcmV0dXJuIERvY3VtZW50Owp9KCkpOwpEb2N1bWVudC5wcm90b3R5cGUuJGF1dG9OZXdMaW5lID0gIiI7CkRvY3VtZW50LnByb3RvdHlwZS4kbmV3TGluZU1vZGUgPSAiYXV0byI7Cm9vcC5pbXBsZW1lbnQoRG9jdW1lbnQucHJvdG90eXBlLCBFdmVudEVtaXR0ZXIpOwpleHBvcnRzLkRvY3VtZW50ID0gRG9jdW1lbnQ7Cgp9KTsKCmFjZS5kZWZpbmUoImFjZS9saWIvZGVlcF9jb3B5IixbXSwgZnVuY3Rpb24ocmVxdWlyZSwgZXhwb3J0cywgbW9kdWxlKXtleHBvcnRzLmRlZXBDb3B5ID0gZnVuY3Rpb24gZGVlcENvcHkob2JqKSB7CiAgICBpZiAodHlwZW9mIG9iaiAhPT0gIm9iamVjdCIgfHwgIW9iaikKICAgICAgICByZXR1cm4gb2JqOwogICAgdmFyIGNvcHk7CiAgICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7CiAgICAgICAgY29weSA9IFtdOwogICAgICAgIGZvciAodmFyIGtleSA9IDA7IGtleSA8IG9iai5sZW5ndGg7IGtleSsrKSB7CiAgICAgICAgICAgIGNvcHlba2V5XSA9IGRlZXBDb3B5KG9ialtrZXldKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvcHk7CiAgICB9CiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iaikgIT09ICJbb2JqZWN0IE9iamVjdF0iKQogICAgICAgIHJldHVybiBvYmo7CiAgICBjb3B5ID0ge307CiAgICBmb3IgKHZhciBrZXkgaW4gb2JqKQogICAgICAgIGNvcHlba2V5XSA9IGRlZXBDb3B5KG9ialtrZXldKTsKICAgIHJldHVybiBjb3B5Owp9OwoKfSk7CgphY2UuZGVmaW5lKCJhY2UvbGliL2xhbmciLFtdLCBmdW5jdGlvbihyZXF1aXJlLCBleHBvcnRzLCBtb2R1bGUpeyJ1c2Ugc3RyaWN0IjsKZXhwb3J0cy5sYXN0ID0gZnVuY3Rpb24gKGEpIHsKICAgIHJldHVybiBhW2EubGVuZ3RoIC0gMV07Cn07CmV4cG9ydHMuc3RyaW5nUmV2ZXJzZSA9IGZ1bmN0aW9uIChzdHJpbmcpIHsKICAgIHJldHVybiBzdHJpbmcuc3BsaXQoIiIpLnJldmVyc2UoKS5qb2luKCIiKTsKfTsKZXhwb3J0cy5zdHJpbmdSZXBlYXQgPSBmdW5jdGlvbiAoc3RyaW5nLCBjb3VudCkgewogICAgdmFyIHJlc3VsdCA9ICcnOwogICAgd2hpbGUgKGNvdW50ID4gMCkgewogICAgICAgIGlmIChjb3VudCAmIDEpCiAgICAgICAgICAgIHJlc3VsdCArPSBzdHJpbmc7CiAgICAgICAgaWYgKGNvdW50ID4+PSAxKQogICAgICAgICAgICBzdHJpbmcgKz0gc3RyaW5nOwogICAgfQogICAgcmV0dXJuIHJlc3VsdDsKfTsKdmFyIHRyaW1CZWdpblJlZ2V4cCA9IC9eXHNccyovOwp2YXIgdHJpbUVuZFJlZ2V4cCA9IC9cc1xzKiQvOwpleHBvcnRzLnN0cmluZ1RyaW1MZWZ0ID0gZnVuY3Rpb24gKHN0cmluZykgewogICAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKHRyaW1CZWdpblJlZ2V4cCwgJycpOwp9OwpleHBvcnRzLnN0cmluZ1RyaW1SaWdodCA9IGZ1bmN0aW9uIChzdHJpbmcpIHsKICAgIHJldHVybiBzdHJpbmcucmVwbGFjZSh0cmltRW5kUmVnZXhwLCAnJyk7Cn07CmV4cG9ydHMuY29weU9iamVjdCA9IGZ1bmN0aW9uIChvYmopIHsKICAgIHZhciBjb3B5ID0ge307CiAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7CiAgICAgICAgY29weVtrZXldID0gb2JqW2tleV07CiAgICB9CiAgICByZXR1cm4gY29weTsKfTsKZXhwb3J0cy5jb3B5QXJyYXkgPSBmdW5jdGlvbiAoYXJyYXkpIHsKICAgIHZhciBjb3B5ID0gW107CiAgICBmb3IgKHZhciBpID0gMCwgbCA9IGFycmF5Lmxlbmd0aDsgaSA8IGw7IGkrKykgewogICAgICAgIGlmIChhcnJheVtpXSAmJiB0eXBlb2YgYXJyYXlbaV0gPT0gIm9iamVjdCIpCiAgICAgICAgICAgIGNvcHlbaV0gPSB0aGlzLmNvcHlPYmplY3QoYXJyYXlbaV0pOwogICAgICAgIGVsc2UKICAgICAgICAgICAgY29weVtpXSA9IGFycmF5W2ldOwogICAgfQogICAgcmV0dXJuIGNvcHk7Cn07CmV4cG9ydHMuZGVlcENvcHkgPSByZXF1aXJlKCIuL2RlZXBfY29weSIpLmRlZXBDb3B5OwpleHBvcnRzLmFycmF5VG9NYXAgPSBmdW5jdGlvbiAoYXJyKSB7CiAgICB2YXIgbWFwID0ge307CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykgewogICAgICAgIG1hcFthcnJbaV1dID0gMTsKICAgIH0KICAgIHJldHVybiBtYXA7Cn07CmV4cG9ydHMuY3JlYXRlTWFwID0gZnVuY3Rpb24gKHByb3BzKSB7CiAgICB2YXIgbWFwID0gT2JqZWN0LmNyZWF0ZShudWxsKTsKICAgIGZvciAodmFyIGkgaW4gcHJvcHMpIHsKICAgICAgICBtYXBbaV0gPSBwcm9wc1tpXTsKICAgIH0KICAgIHJldHVybiBtYXA7Cn07CmV4cG9ydHMuYXJyYXlSZW1vdmUgPSBmdW5jdGlvbiAoYXJyYXksIHZhbHVlKSB7CiAgICBmb3IgKHZhciBpID0gMDsgaSA8PSBhcnJheS5sZW5ndGg7IGkrKykgewogICAgICAgIGlmICh2YWx1ZSA9PT0gYXJyYXlbaV0pIHsKICAgICAgICAgICAgYXJyYXkuc3BsaWNlKGksIDEpOwogICAgICAgIH0KICAgIH0KfTsKZXhwb3J0cy5lc2NhcGVSZWdFeHAgPSBmdW5jdGlvbiAoc3RyKSB7CiAgICByZXR1cm4gc3RyLnJlcGxhY2UoLyhbLiorP14ke30oKXxbXF1cL1xcXSkvZywgJ1xcJDEnKTsKfTsKZXhwb3J0cy5lc2NhcGVIVE1MID0gZnVuY3Rpb24gKHN0cikgewogICAgcmV0dXJuICgiIiArIHN0cikucmVwbGFjZSgvJi9nLCAiJiMzODsiKS5yZXBsYWNlKC8iL2csICImIzM0OyIpLnJlcGxhY2UoLycvZywgIiYjMzk7IikucmVwbGFjZSgvPC9nLCAiJiM2MDsiKTsKfTsKZXhwb3J0cy5nZXRNYXRjaE9mZnNldHMgPSBmdW5jdGlvbiAoc3RyaW5nLCByZWdFeHApIHsKICAgIHZhciBtYXRjaGVzID0gW107CiAgICBzdHJpbmcucmVwbGFjZShyZWdFeHAsIGZ1bmN0aW9uIChzdHIpIHsKICAgICAgICBtYXRjaGVzLnB1c2goewogICAgICAgICAgICBvZmZzZXQ6IGFyZ3VtZW50c1thcmd1bWVudHMubGVuZ3RoIC0gMl0sCiAgICAgICAgICAgIGxlbmd0aDogc3RyLmxlbmd0aAogICAgICAgIH0pOwogICAgfSk7CiAgICByZXR1cm4gbWF0Y2hlczsKfTsKZXhwb3J0cy5kZWZlcnJlZENhbGwgPSBmdW5jdGlvbiAoZmNuKSB7CiAgICB2YXIgdGltZXIgPSBudWxsOwogICAgdmFyIGNhbGxiYWNrID0gZnVuY3Rpb24gKCkgewogICAgICAgIHRpbWVyID0gbnVsbDsKICAgICAgICBmY24oKTsKICAgIH07CiAgICB2YXIgZGVmZXJyZWQgPSBmdW5jdGlvbiAodGltZW91dCkgewogICAgICAgIGRlZmVycmVkLmNhbmNlbCgpOwogICAgICAgIHRpbWVyID0gc2V0VGltZW91dChjYWxsYmFjaywgdGltZW91dCB8fCAwKTsKICAgICAgICByZXR1cm4gZGVmZXJyZWQ7CiAgICB9OwogICAgZGVmZXJyZWQuc2NoZWR1bGUgPSBkZWZlcnJlZDsKICAgIGRlZmVycmVkLmNhbGwgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdGhpcy5jYW5jZWwoKTsKICAgICAgICBmY24oKTsKICAgICAgICByZXR1cm4gZGVmZXJyZWQ7CiAgICB9OwogICAgZGVmZXJyZWQuY2FuY2VsID0gZnVuY3Rpb24gKCkgewogICAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7CiAgICAgICAgdGltZXIgPSBudWxsOwogICAgICAgIHJldHVybiBkZWZlcnJlZDsKICAgIH07CiAgICBkZWZlcnJlZC5pc1BlbmRpbmcgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgcmV0dXJuIHRpbWVyOwogICAgfTsKICAgIHJldHVybiBkZWZlcnJlZDsKfTsKZXhwb3J0cy5kZWxheWVkQ2FsbCA9IGZ1bmN0aW9uIChmY24sIGRlZmF1bHRUaW1lb3V0KSB7CiAgICB2YXIgdGltZXIgPSBudWxsOwogICAgdmFyIGNhbGxiYWNrID0gZnVuY3Rpb24gKCkgewogICAgICAgIHRpbWVyID0gbnVsbDsKICAgICAgICBmY24oKTsKICAgIH07CiAgICB2YXIgX3NlbGYgPSBmdW5jdGlvbiAodGltZW91dCkgewogICAgICAgIGlmICh0aW1lciA9PSBudWxsKQogICAgICAgICAgICB0aW1lciA9IHNldFRpbWVvdXQoY2FsbGJhY2ssIHRpbWVvdXQgfHwgZGVmYXVsdFRpbWVvdXQpOwogICAgfTsKICAgIF9zZWxmLmRlbGF5ID0gZnVuY3Rpb24gKHRpbWVvdXQpIHsKICAgICAgICB0aW1lciAmJiBjbGVhclRpbWVvdXQodGltZXIpOwogICAgICAgIHRpbWVyID0gc2V0VGltZW91dChjYWxsYmFjaywgdGltZW91dCB8fCBkZWZhdWx0VGltZW91dCk7CiAgICB9OwogICAgX3NlbGYuc2NoZWR1bGUgPSBfc2VsZjsKICAgIF9zZWxmLmNhbGwgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdGhpcy5jYW5jZWwoKTsKICAgICAgICBmY24oKTsKICAgIH07CiAgICBfc2VsZi5jYW5jZWwgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdGltZXIgJiYgY2xlYXJUaW1lb3V0KHRpbWVyKTsKICAgICAgICB0aW1lciA9IG51bGw7CiAgICB9OwogICAgX3NlbGYuaXNQZW5kaW5nID0gZnVuY3Rpb24gKCkgewogICAgICAgIHJldHVybiB0aW1lcjsKICAgIH07CiAgICByZXR1cm4gX3NlbGY7Cn07CmV4cG9ydHMuc2xlZXAgPSBmdW5jdGlvbiAobXMpIHsKICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkgewogICAgICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpOwogICAgfSk7Cn07CmV4cG9ydHMuc3VwcG9ydHNMb29rYmVoaW5kID0gZnVuY3Rpb24gKCkgewogICAgdHJ5IHsKICAgICAgICBuZXcgUmVnRXhwKCcoPzw9LiknKTsKICAgIH0KICAgIGNhdGNoIChlKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgcmV0dXJuIHRydWU7Cn07CmV4cG9ydHMuc2tpcEVtcHR5TWF0Y2ggPSBmdW5jdGlvbiAobGluZSwgbGFzdCwgc3VwcG9ydHNVbmljb2RlRmxhZykgewogICAgcmV0dXJuIHN1cHBvcnRzVW5pY29kZUZsYWcgJiYgbGluZS5jb2RlUG9pbnRBdChsYXN0KSA+IDB4ZmZmZiA/IDIgOiAxOwp9OwoKfSk7CgphY2UuZGVmaW5lKCJhY2Uvd29ya2VyL21pcnJvciIsW10sIGZ1bmN0aW9uKHJlcXVpcmUsIGV4cG9ydHMsIG1vZHVsZSkgewoidXNlIHN0cmljdCI7Cgp2YXIgRG9jdW1lbnQgPSByZXF1aXJlKCIuLi9kb2N1bWVudCIpLkRvY3VtZW50Owp2YXIgbGFuZyA9IHJlcXVpcmUoIi4uL2xpYi9sYW5nIik7CiAgICAKdmFyIE1pcnJvciA9IGV4cG9ydHMuTWlycm9yID0gZnVuY3Rpb24oc2VuZGVyKSB7CiAgICB0aGlzLnNlbmRlciA9IHNlbmRlcjsKICAgIHZhciBkb2MgPSB0aGlzLmRvYyA9IG5ldyBEb2N1bWVudCgiIik7CiAgICAKICAgIHZhciBkZWZlcnJlZFVwZGF0ZSA9IHRoaXMuZGVmZXJyZWRVcGRhdGUgPSBsYW5nLmRlbGF5ZWRDYWxsKHRoaXMub25VcGRhdGUuYmluZCh0aGlzKSk7CiAgICAKICAgIHZhciBfc2VsZiA9IHRoaXM7CiAgICBzZW5kZXIub24oImNoYW5nZSIsIGZ1bmN0aW9uKGUpIHsKICAgICAgICB2YXIgZGF0YSA9IGUuZGF0YTsKICAgICAgICBpZiAoZGF0YVswXS5zdGFydCkgewogICAgICAgICAgICBkb2MuYXBwbHlEZWx0YXMoZGF0YSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSArPSAyKSB7CiAgICAgICAgICAgICAgICB2YXIgZCwgZXJyOyAKICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGFbaSsxXSkpIHsKICAgICAgICAgICAgICAgICAgICBkID0ge2FjdGlvbjogImluc2VydCIsIHN0YXJ0OiBkYXRhW2ldLCBsaW5lczogZGF0YVtpKzFdfTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZCA9IHthY3Rpb246ICJyZW1vdmUiLCBzdGFydDogZGF0YVtpXSwgZW5kOiBkYXRhW2krMV19OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBpZiAoKGQuYWN0aW9uID09ICJpbnNlcnQiID8gZC5zdGFydCA6IGQuZW5kKS5yb3cgPj0gZG9jLiRsaW5lcy5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICBlcnIgPSBuZXcgRXJyb3IoIkludmFsaWQgZGVsdGEiKTsKICAgICAgICAgICAgICAgICAgICBlcnIuZGF0YSA9IHsKICAgICAgICAgICAgICAgICAgICAgICAgcGF0aDogX3NlbGYuJHBhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVzTGVuZ3RoOiBkb2MuJGxpbmVzLmxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnQ6IGQuc3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgIGVuZDogZC5lbmQKICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgIHRocm93IGVycjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBkb2MuYXBwbHlEZWx0YShkLCB0cnVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoX3NlbGYuJHRpbWVvdXQpCiAgICAgICAgICAgIHJldHVybiBkZWZlcnJlZFVwZGF0ZS5zY2hlZHVsZShfc2VsZi4kdGltZW91dCk7CiAgICAgICAgX3NlbGYub25VcGRhdGUoKTsKICAgIH0pOwp9OwoKKGZ1bmN0aW9uKCkgewogICAgCiAgICB0aGlzLiR0aW1lb3V0ID0gNTAwOwogICAgCiAgICB0aGlzLnNldFRpbWVvdXQgPSBmdW5jdGlvbih0aW1lb3V0KSB7CiAgICAgICAgdGhpcy4kdGltZW91dCA9IHRpbWVvdXQ7CiAgICB9OwogICAgCiAgICB0aGlzLnNldFZhbHVlID0gZnVuY3Rpb24odmFsdWUpIHsKICAgICAgICB0aGlzLmRvYy5zZXRWYWx1ZSh2YWx1ZSk7CiAgICAgICAgdGhpcy5kZWZlcnJlZFVwZGF0ZS5zY2hlZHVsZSh0aGlzLiR0aW1lb3V0KTsKICAgIH07CiAgICAKICAgIHRoaXMuZ2V0VmFsdWUgPSBmdW5jdGlvbihjYWxsYmFja0lkKSB7CiAgICAgICAgdGhpcy5zZW5kZXIuY2FsbGJhY2sodGhpcy5kb2MuZ2V0VmFsdWUoKSwgY2FsbGJhY2tJZCk7CiAgICB9OwogICAgCiAgICB0aGlzLm9uVXBkYXRlID0gZnVuY3Rpb24oKSB7CiAgICB9OwogICAgCiAgICB0aGlzLmlzUGVuZGluZyA9IGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiB0aGlzLmRlZmVycmVkVXBkYXRlLmlzUGVuZGluZygpOwogICAgfTsKICAgIAp9KS5jYWxsKE1pcnJvci5wcm90b3R5cGUpOwoKfSk7CgphY2UuZGVmaW5lKCJhY2UvbW9kZS95YW1sL3lhbWwtbGludCIsW10sIGZ1bmN0aW9uKHJlcXVpcmUsIGV4cG9ydHMsIG1vZHVsZSkgewp2YXIgJGJ1aWxkX2RlcHMkID0ge3JlcXVpcmU6IHJlcXVpcmUsIGV4cG9ydHM6IGV4cG9ydHMsIG1vZHVsZTogbW9kdWxlfTsKZXhwb3J0cyA9IHVuZGVmaW5lZDsgbW9kdWxlID0gdW5kZWZpbmVkOwpmdW5jdGlvbiBkZWZpbmUobmFtZSwgZGVwcywgbSkgewogICAgaWYgKHR5cGVvZiBuYW1lID09ICJmdW5jdGlvbiIpIHsKICAgICAgICBtID0gbmFtZTsgZGVwcyA9IFsicmVxdWlyZSIsICJleHBvcnRzIiwgIm1vZHVsZSJdOyBuYW1lID0gJGJ1aWxkX2RlcHMkLm1vZHVsZS5pZAogICAgfQogICAgaWYgKHR5cGVvZiBuYW1lICE9PSAic3RyaW5nIikgewogICAgICAgIG0gPSBkZXBzOyBkZXBzID0gbmFtZTsgbmFtZSA9ICRidWlsZF9kZXBzJC5tb2R1bGUuaWQKICAgIH0KICAgIGlmICghbSkgewogICAgICAgIG0gPSBkZXBzOyBkZXBzID0gW107CiAgICB9CiAgIHZhciByZXQgPSB0eXBlb2YgbSA9PSAiZnVuY3Rpb24iID8KICAgICAgIG0uYXBwbHkoJGJ1aWxkX2RlcHMkLm1vZHVsZSwgZGVwcy5tYXAoZnVuY3Rpb24obil7cmV0dXJuICRidWlsZF9kZXBzJFtuXSB8fCByZXF1aXJlKG4pfSkpIDogbQogICBpZiAocmV0ICE9IHVuZGVmaW5lZCkgJGJ1aWxkX2RlcHMkLm1vZHVsZS5leHBvcnRzID0gcmV0Owp9CmRlZmluZS5hbWQgPSB0cnVlOyhmdW5jdGlvbihmKXtpZih0eXBlb2YgZXhwb3J0cz09PSJvYmplY3QiJiZ0eXBlb2YgbW9kdWxlIT09InVuZGVmaW5lZCIpe21vZHVsZS5leHBvcnRzPWYoKTt9ZWxzZSBpZih0eXBlb2YgZGVmaW5lPT09ImZ1bmN0aW9uIiYmZGVmaW5lLmFtZCl7ZGVmaW5lKFtdLGYpO31lbHNle3ZhciBnO2lmKHR5cGVvZiB3aW5kb3chPT0idW5kZWZpbmVkIil7Zz13aW5kb3c7fWVsc2UgaWYodHlwZW9mIGdsb2JhbCE9PSJ1bmRlZmluZWQiKXtnPWdsb2JhbDt9ZWxzZSBpZih0eXBlb2Ygc2VsZiE9PSJ1bmRlZmluZWQiKXtnPXNlbGY7fWVsc2V7Zz10aGlzO31nLmxpbnQgPSBmKCk7fX0pKGZ1bmN0aW9uKCl7dmFyIGRlZmluZSxtb2R1bGUsZXhwb3J0cztyZXR1cm4gKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gcihlLG4sdCl7ZnVuY3Rpb24gbyhpLGYpe2lmKCFuW2ldKXtpZighZVtpXSl7dmFyIGM9dHlwZW9mIHJlcXVpcmU9PSJmdW5jdGlvbiImJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoIkNhbm5vdCBmaW5kIG1vZHVsZSAnIitpKyInIik7dGhyb3cgYS5jb2RlPSJNT0RVTEVfTk9UX0ZPVU5EIixhO312YXIgcD1uW2ldPXtleHBvcnRzOnt9fTtlW2ldWzBdLmNhbGwocC5leHBvcnRzLGZ1bmN0aW9uKHIpe3ZhciBuPWVbaV1bMV1bcl07cmV0dXJuIG8obnx8cik7fSxwLHAuZXhwb3J0cyxyLGUsbix0KTt9cmV0dXJuIG5baV0uZXhwb3J0czt9Zm9yKHZhciB1PXR5cGVvZiByZXF1aXJlPT0iZnVuY3Rpb24iJiZyZXF1aXJlLGk9MDtpPHQubGVuZ3RoO2krKylvKHRbaV0pO3JldHVybiBvO31yZXR1cm4gcjt9KSgpKHsxOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKCn0se31dLDI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewp2YXIgZnMgPSByZXF1aXJlKCdmcycpOwp2YXIgbWVyZ2UgPSByZXF1aXJlKCdsb2Rhc2gubWVyZ2UnKTsKdmFyIHlhbWwgPSByZXF1aXJlKCdqcy15YW1sJyk7Cgp2YXIgREVGQVVMVF9MSU5UX09QVElPTiA9IHsKICBzY2hlbWE6ICdERUZBVUxUX1NBRkVfU0NIRU1BJwp9OwoKZnVuY3Rpb24gbGludChjb250ZW50LCBvcHRzLCBjYikgewoKICB2YXIgb3B0aW9ucyA9IG1lcmdlKHt9LCBERUZBVUxUX0xJTlRfT1BUSU9OLCBvcHRzKTsKICB0cnkgewogICAgeWFtbC5zYWZlTG9hZChjb250ZW50LCB7CiAgICAgIHNjaGVtYTogeWFtbFtvcHRpb25zLnNjaGVtYV0KICAgIH0pOwogICAgY2IoKTsKICB9IGNhdGNoIChlKSB7CiAgICBjYihlKTsKICB9Cn0KCm1vZHVsZS5leHBvcnRzID0gewogIGxpbnQ6IGxpbnQKfTsKCn0seyJmcyI6MSwianMteWFtbCI6MywibG9kYXNoLm1lcmdlIjozM31dLDM6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgoKdmFyIHlhbWwgPSByZXF1aXJlKCcuL2xpYi9qcy15YW1sLmpzJyk7CgoKbW9kdWxlLmV4cG9ydHMgPSB5YW1sOwoKfSx7Ii4vbGliL2pzLXlhbWwuanMiOjR9XSw0OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKCnZhciBsb2FkZXIgPSByZXF1aXJlKCcuL2pzLXlhbWwvbG9hZGVyJyk7CnZhciBkdW1wZXIgPSByZXF1aXJlKCcuL2pzLXlhbWwvZHVtcGVyJyk7CgoKZnVuY3Rpb24gZGVwcmVjYXRlZChuYW1lKSB7CiAgcmV0dXJuIGZ1bmN0aW9uICgpIHsKICAgIHRocm93IG5ldyBFcnJvcignRnVuY3Rpb24gJyArIG5hbWUgKyAnIGlzIGRlcHJlY2F0ZWQgYW5kIGNhbm5vdCBiZSB1c2VkLicpOwogIH07Cn0KCgptb2R1bGUuZXhwb3J0cy5UeXBlICAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9qcy15YW1sL3R5cGUnKTsKbW9kdWxlLmV4cG9ydHMuU2NoZW1hICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEnKTsKbW9kdWxlLmV4cG9ydHMuRkFJTFNBRkVfU0NIRU1BICAgICA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvZmFpbHNhZmUnKTsKbW9kdWxlLmV4cG9ydHMuSlNPTl9TQ0hFTUEgICAgICAgICA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvanNvbicpOwptb2R1bGUuZXhwb3J0cy5DT1JFX1NDSEVNQSAgICAgICAgID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9jb3JlJyk7Cm1vZHVsZS5leHBvcnRzLkRFRkFVTFRfU0FGRV9TQ0hFTUEgPSByZXF1aXJlKCcuL2pzLXlhbWwvc2NoZW1hL2RlZmF1bHRfc2FmZScpOwptb2R1bGUuZXhwb3J0cy5ERUZBVUxUX0ZVTExfU0NIRU1BID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9kZWZhdWx0X2Z1bGwnKTsKbW9kdWxlLmV4cG9ydHMubG9hZCAgICAgICAgICAgICAgICA9IGxvYWRlci5sb2FkOwptb2R1bGUuZXhwb3J0cy5sb2FkQWxsICAgICAgICAgICAgID0gbG9hZGVyLmxvYWRBbGw7Cm1vZHVsZS5leHBvcnRzLnNhZmVMb2FkICAgICAgICAgICAgPSBsb2FkZXIuc2FmZUxvYWQ7Cm1vZHVsZS5leHBvcnRzLnNhZmVMb2FkQWxsICAgICAgICAgPSBsb2FkZXIuc2FmZUxvYWRBbGw7Cm1vZHVsZS5leHBvcnRzLmR1bXAgICAgICAgICAgICAgICAgPSBkdW1wZXIuZHVtcDsKbW9kdWxlLmV4cG9ydHMuc2FmZUR1bXAgICAgICAgICAgICA9IGR1bXBlci5zYWZlRHVtcDsKbW9kdWxlLmV4cG9ydHMuWUFNTEV4Y2VwdGlvbiAgICAgICA9IHJlcXVpcmUoJy4vanMteWFtbC9leGNlcHRpb24nKTsKbW9kdWxlLmV4cG9ydHMuTUlOSU1BTF9TQ0hFTUEgPSByZXF1aXJlKCcuL2pzLXlhbWwvc2NoZW1hL2ZhaWxzYWZlJyk7Cm1vZHVsZS5leHBvcnRzLlNBRkVfU0NIRU1BICAgID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9kZWZhdWx0X3NhZmUnKTsKbW9kdWxlLmV4cG9ydHMuREVGQVVMVF9TQ0hFTUEgPSByZXF1aXJlKCcuL2pzLXlhbWwvc2NoZW1hL2RlZmF1bHRfZnVsbCcpOwptb2R1bGUuZXhwb3J0cy5zY2FuICAgICAgICAgICA9IGRlcHJlY2F0ZWQoJ3NjYW4nKTsKbW9kdWxlLmV4cG9ydHMucGFyc2UgICAgICAgICAgPSBkZXByZWNhdGVkKCdwYXJzZScpOwptb2R1bGUuZXhwb3J0cy5jb21wb3NlICAgICAgICA9IGRlcHJlY2F0ZWQoJ2NvbXBvc2UnKTsKbW9kdWxlLmV4cG9ydHMuYWRkQ29uc3RydWN0b3IgPSBkZXByZWNhdGVkKCdhZGRDb25zdHJ1Y3RvcicpOwoKfSx7Ii4vanMteWFtbC9kdW1wZXIiOjYsIi4vanMteWFtbC9leGNlcHRpb24iOjcsIi4vanMteWFtbC9sb2FkZXIiOjgsIi4vanMteWFtbC9zY2hlbWEiOjEwLCIuL2pzLXlhbWwvc2NoZW1hL2NvcmUiOjExLCIuL2pzLXlhbWwvc2NoZW1hL2RlZmF1bHRfZnVsbCI6MTIsIi4vanMteWFtbC9zY2hlbWEvZGVmYXVsdF9zYWZlIjoxMywiLi9qcy15YW1sL3NjaGVtYS9mYWlsc2FmZSI6MTQsIi4vanMteWFtbC9zY2hlbWEvanNvbiI6MTUsIi4vanMteWFtbC90eXBlIjoxNn1dLDU6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgoKZnVuY3Rpb24gaXNOb3RoaW5nKHN1YmplY3QpIHsKICByZXR1cm4gKHR5cGVvZiBzdWJqZWN0ID09PSAndW5kZWZpbmVkJykgfHwgKHN1YmplY3QgPT09IG51bGwpOwp9CgoKZnVuY3Rpb24gaXNPYmplY3Qoc3ViamVjdCkgewogIHJldHVybiAodHlwZW9mIHN1YmplY3QgPT09ICdvYmplY3QnKSAmJiAoc3ViamVjdCAhPT0gbnVsbCk7Cn0KCgpmdW5jdGlvbiB0b0FycmF5KHNlcXVlbmNlKSB7CiAgaWYgKEFycmF5LmlzQXJyYXkoc2VxdWVuY2UpKSByZXR1cm4gc2VxdWVuY2U7CiAgZWxzZSBpZiAoaXNOb3RoaW5nKHNlcXVlbmNlKSkgcmV0dXJuIFtdOwoKICByZXR1cm4gWyBzZXF1ZW5jZSBdOwp9CgoKZnVuY3Rpb24gZXh0ZW5kKHRhcmdldCwgc291cmNlKSB7CiAgdmFyIGluZGV4LCBsZW5ndGgsIGtleSwgc291cmNlS2V5czsKCiAgaWYgKHNvdXJjZSkgewogICAgc291cmNlS2V5cyA9IE9iamVjdC5rZXlzKHNvdXJjZSk7CgogICAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IHNvdXJjZUtleXMubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkgewogICAgICBrZXkgPSBzb3VyY2VLZXlzW2luZGV4XTsKICAgICAgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsKICAgIH0KICB9CgogIHJldHVybiB0YXJnZXQ7Cn0KCgpmdW5jdGlvbiByZXBlYXQoc3RyaW5nLCBjb3VudCkgewogIHZhciByZXN1bHQgPSAnJywgY3ljbGU7CgogIGZvciAoY3ljbGUgPSAwOyBjeWNsZSA8IGNvdW50OyBjeWNsZSArPSAxKSB7CiAgICByZXN1bHQgKz0gc3RyaW5nOwogIH0KCiAgcmV0dXJuIHJlc3VsdDsKfQoKCmZ1bmN0aW9uIGlzTmVnYXRpdmVaZXJvKG51bWJlcikgewogIHJldHVybiAobnVtYmVyID09PSAwKSAmJiAoTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZID09PSAxIC8gbnVtYmVyKTsKfQoKCm1vZHVsZS5leHBvcnRzLmlzTm90aGluZyAgICAgID0gaXNOb3RoaW5nOwptb2R1bGUuZXhwb3J0cy5pc09iamVjdCAgICAgICA9IGlzT2JqZWN0Owptb2R1bGUuZXhwb3J0cy50b0FycmF5ICAgICAgICA9IHRvQXJyYXk7Cm1vZHVsZS5leHBvcnRzLnJlcGVhdCAgICAgICAgID0gcmVwZWF0Owptb2R1bGUuZXhwb3J0cy5pc05lZ2F0aXZlWmVybyA9IGlzTmVnYXRpdmVaZXJvOwptb2R1bGUuZXhwb3J0cy5leHRlbmQgICAgICAgICA9IGV4dGVuZDsKCn0se31dLDY6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7Cgp2YXIgY29tbW9uICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vY29tbW9uJyk7CnZhciBZQU1MRXhjZXB0aW9uICAgICAgID0gcmVxdWlyZSgnLi9leGNlcHRpb24nKTsKdmFyIERFRkFVTFRfRlVMTF9TQ0hFTUEgPSByZXF1aXJlKCcuL3NjaGVtYS9kZWZhdWx0X2Z1bGwnKTsKdmFyIERFRkFVTFRfU0FGRV9TQ0hFTUEgPSByZXF1aXJlKCcuL3NjaGVtYS9kZWZhdWx0X3NhZmUnKTsKCnZhciBfdG9TdHJpbmcgICAgICAgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nOwp2YXIgX2hhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTsKCnZhciBDSEFSX1RBQiAgICAgICAgICAgICAgICAgID0gMHgwOTsKdmFyIENIQVJfTElORV9GRUVEICAgICAgICAgICAgPSAweDBBOwp2YXIgQ0hBUl9TUEFDRSAgICAgICAgICAgICAgICA9IDB4MjA7CnZhciBDSEFSX0VYQ0xBTUFUSU9OICAgICAgICAgID0gMHgyMTsKdmFyIENIQVJfRE9VQkxFX1FVT1RFICAgICAgICAgPSAweDIyOwp2YXIgQ0hBUl9TSEFSUCAgICAgICAgICAgICAgICA9IDB4MjM7CnZhciBDSEFSX1BFUkNFTlQgICAgICAgICAgICAgID0gMHgyNTsKdmFyIENIQVJfQU1QRVJTQU5EICAgICAgICAgICAgPSAweDI2Owp2YXIgQ0hBUl9TSU5HTEVfUVVPVEUgICAgICAgICA9IDB4Mjc7CnZhciBDSEFSX0FTVEVSSVNLICAgICAgICAgICAgID0gMHgyQTsKdmFyIENIQVJfQ09NTUEgICAgICAgICAgICAgICAgPSAweDJDOwp2YXIgQ0hBUl9NSU5VUyAgICAgICAgICAgICAgICA9IDB4MkQ7CnZhciBDSEFSX0NPTE9OICAgICAgICAgICAgICAgID0gMHgzQTsKdmFyIENIQVJfR1JFQVRFUl9USEFOICAgICAgICAgPSAweDNFOwp2YXIgQ0hBUl9RVUVTVElPTiAgICAgICAgICAgICA9IDB4M0Y7CnZhciBDSEFSX0NPTU1FUkNJQUxfQVQgICAgICAgID0gMHg0MDsKdmFyIENIQVJfTEVGVF9TUVVBUkVfQlJBQ0tFVCAgPSAweDVCOwp2YXIgQ0hBUl9SSUdIVF9TUVVBUkVfQlJBQ0tFVCA9IDB4NUQ7CnZhciBDSEFSX0dSQVZFX0FDQ0VOVCAgICAgICAgID0gMHg2MDsKdmFyIENIQVJfTEVGVF9DVVJMWV9CUkFDS0VUICAgPSAweDdCOwp2YXIgQ0hBUl9WRVJUSUNBTF9MSU5FICAgICAgICA9IDB4N0M7CnZhciBDSEFSX1JJR0hUX0NVUkxZX0JSQUNLRVQgID0gMHg3RDsKCnZhciBFU0NBUEVfU0VRVUVOQ0VTID0ge307CgpFU0NBUEVfU0VRVUVOQ0VTWzB4MDBdICAgPSAnXFwwJzsKRVNDQVBFX1NFUVVFTkNFU1sweDA3XSAgID0gJ1xcYSc7CkVTQ0FQRV9TRVFVRU5DRVNbMHgwOF0gICA9ICdcXGInOwpFU0NBUEVfU0VRVUVOQ0VTWzB4MDldICAgPSAnXFx0JzsKRVNDQVBFX1NFUVVFTkNFU1sweDBBXSAgID0gJ1xcbic7CkVTQ0FQRV9TRVFVRU5DRVNbMHgwQl0gICA9ICdcXHYnOwpFU0NBUEVfU0VRVUVOQ0VTWzB4MENdICAgPSAnXFxmJzsKRVNDQVBFX1NFUVVFTkNFU1sweDBEXSAgID0gJ1xccic7CkVTQ0FQRV9TRVFVRU5DRVNbMHgxQl0gICA9ICdcXGUnOwpFU0NBUEVfU0VRVUVOQ0VTWzB4MjJdICAgPSAnXFwiJzsKRVNDQVBFX1NFUVVFTkNFU1sweDVDXSAgID0gJ1xcXFwnOwpFU0NBUEVfU0VRVUVOQ0VTWzB4ODVdICAgPSAnXFxOJzsKRVNDQVBFX1NFUVVFTkNFU1sweEEwXSAgID0gJ1xcXyc7CkVTQ0FQRV9TRVFVRU5DRVNbMHgyMDI4XSA9ICdcXEwnOwpFU0NBUEVfU0VRVUVOQ0VTWzB4MjAyOV0gPSAnXFxQJzsKCnZhciBERVBSRUNBVEVEX0JPT0xFQU5TX1NZTlRBWCA9IFsKICAneScsICdZJywgJ3llcycsICdZZXMnLCAnWUVTJywgJ29uJywgJ09uJywgJ09OJywKICAnbicsICdOJywgJ25vJywgJ05vJywgJ05PJywgJ29mZicsICdPZmYnLCAnT0ZGJwpdOwoKZnVuY3Rpb24gY29tcGlsZVN0eWxlTWFwKHNjaGVtYSwgbWFwKSB7CiAgdmFyIHJlc3VsdCwga2V5cywgaW5kZXgsIGxlbmd0aCwgdGFnLCBzdHlsZSwgdHlwZTsKCiAgaWYgKG1hcCA9PT0gbnVsbCkgcmV0dXJuIHt9OwoKICByZXN1bHQgPSB7fTsKICBrZXlzID0gT2JqZWN0LmtleXMobWFwKTsKCiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IGtleXMubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkgewogICAgdGFnID0ga2V5c1tpbmRleF07CiAgICBzdHlsZSA9IFN0cmluZyhtYXBbdGFnXSk7CgogICAgaWYgKHRhZy5zbGljZSgwLCAyKSA9PT0gJyEhJykgewogICAgICB0YWcgPSAndGFnOnlhbWwub3JnLDIwMDI6JyArIHRhZy5zbGljZSgyKTsKICAgIH0KICAgIHR5cGUgPSBzY2hlbWEuY29tcGlsZWRUeXBlTWFwWydmYWxsYmFjayddW3RhZ107CgogICAgaWYgKHR5cGUgJiYgX2hhc093blByb3BlcnR5LmNhbGwodHlwZS5zdHlsZUFsaWFzZXMsIHN0eWxlKSkgewogICAgICBzdHlsZSA9IHR5cGUuc3R5bGVBbGlhc2VzW3N0eWxlXTsKICAgIH0KCiAgICByZXN1bHRbdGFnXSA9IHN0eWxlOwogIH0KCiAgcmV0dXJuIHJlc3VsdDsKfQoKZnVuY3Rpb24gZW5jb2RlSGV4KGNoYXJhY3RlcikgewogIHZhciBzdHJpbmcsIGhhbmRsZSwgbGVuZ3RoOwoKICBzdHJpbmcgPSBjaGFyYWN0ZXIudG9TdHJpbmcoMTYpLnRvVXBwZXJDYXNlKCk7CgogIGlmIChjaGFyYWN0ZXIgPD0gMHhGRikgewogICAgaGFuZGxlID0gJ3gnOwogICAgbGVuZ3RoID0gMjsKICB9IGVsc2UgaWYgKGNoYXJhY3RlciA8PSAweEZGRkYpIHsKICAgIGhhbmRsZSA9ICd1JzsKICAgIGxlbmd0aCA9IDQ7CiAgfSBlbHNlIGlmIChjaGFyYWN0ZXIgPD0gMHhGRkZGRkZGRikgewogICAgaGFuZGxlID0gJ1UnOwogICAgbGVuZ3RoID0gODsKICB9IGVsc2UgewogICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ2NvZGUgcG9pbnQgd2l0aGluIGEgc3RyaW5nIG1heSBub3QgYmUgZ3JlYXRlciB0aGFuIDB4RkZGRkZGRkYnKTsKICB9CgogIHJldHVybiAnXFwnICsgaGFuZGxlICsgY29tbW9uLnJlcGVhdCgnMCcsIGxlbmd0aCAtIHN0cmluZy5sZW5ndGgpICsgc3RyaW5nOwp9CgpmdW5jdGlvbiBTdGF0ZShvcHRpb25zKSB7CiAgdGhpcy5zY2hlbWEgICAgICAgID0gb3B0aW9uc1snc2NoZW1hJ10gfHwgREVGQVVMVF9GVUxMX1NDSEVNQTsKICB0aGlzLmluZGVudCAgICAgICAgPSBNYXRoLm1heCgxLCAob3B0aW9uc1snaW5kZW50J10gfHwgMikpOwogIHRoaXMubm9BcnJheUluZGVudCA9IG9wdGlvbnNbJ25vQXJyYXlJbmRlbnQnXSB8fCBmYWxzZTsKICB0aGlzLnNraXBJbnZhbGlkICAgPSBvcHRpb25zWydza2lwSW52YWxpZCddIHx8IGZhbHNlOwogIHRoaXMuZmxvd0xldmVsICAgICA9IChjb21tb24uaXNOb3RoaW5nKG9wdGlvbnNbJ2Zsb3dMZXZlbCddKSA/IC0xIDogb3B0aW9uc1snZmxvd0xldmVsJ10pOwogIHRoaXMuc3R5bGVNYXAgICAgICA9IGNvbXBpbGVTdHlsZU1hcCh0aGlzLnNjaGVtYSwgb3B0aW9uc1snc3R5bGVzJ10gfHwgbnVsbCk7CiAgdGhpcy5zb3J0S2V5cyAgICAgID0gb3B0aW9uc1snc29ydEtleXMnXSB8fCBmYWxzZTsKICB0aGlzLmxpbmVXaWR0aCAgICAgPSBvcHRpb25zWydsaW5lV2lkdGgnXSB8fCA4MDsKICB0aGlzLm5vUmVmcyAgICAgICAgPSBvcHRpb25zWydub1JlZnMnXSB8fCBmYWxzZTsKICB0aGlzLm5vQ29tcGF0TW9kZSAgPSBvcHRpb25zWydub0NvbXBhdE1vZGUnXSB8fCBmYWxzZTsKICB0aGlzLmNvbmRlbnNlRmxvdyAgPSBvcHRpb25zWydjb25kZW5zZUZsb3cnXSB8fCBmYWxzZTsKCiAgdGhpcy5pbXBsaWNpdFR5cGVzID0gdGhpcy5zY2hlbWEuY29tcGlsZWRJbXBsaWNpdDsKICB0aGlzLmV4cGxpY2l0VHlwZXMgPSB0aGlzLnNjaGVtYS5jb21waWxlZEV4cGxpY2l0OwoKICB0aGlzLnRhZyA9IG51bGw7CiAgdGhpcy5yZXN1bHQgPSAnJzsKCiAgdGhpcy5kdXBsaWNhdGVzID0gW107CiAgdGhpcy51c2VkRHVwbGljYXRlcyA9IG51bGw7Cn0KZnVuY3Rpb24gaW5kZW50U3RyaW5nKHN0cmluZywgc3BhY2VzKSB7CiAgdmFyIGluZCA9IGNvbW1vbi5yZXBlYXQoJyAnLCBzcGFjZXMpLAogICAgICBwb3NpdGlvbiA9IDAsCiAgICAgIG5leHQgPSAtMSwKICAgICAgcmVzdWx0ID0gJycsCiAgICAgIGxpbmUsCiAgICAgIGxlbmd0aCA9IHN0cmluZy5sZW5ndGg7CgogIHdoaWxlIChwb3NpdGlvbiA8IGxlbmd0aCkgewogICAgbmV4dCA9IHN0cmluZy5pbmRleE9mKCdcbicsIHBvc2l0aW9uKTsKICAgIGlmIChuZXh0ID09PSAtMSkgewogICAgICBsaW5lID0gc3RyaW5nLnNsaWNlKHBvc2l0aW9uKTsKICAgICAgcG9zaXRpb24gPSBsZW5ndGg7CiAgICB9IGVsc2UgewogICAgICBsaW5lID0gc3RyaW5nLnNsaWNlKHBvc2l0aW9uLCBuZXh0ICsgMSk7CiAgICAgIHBvc2l0aW9uID0gbmV4dCArIDE7CiAgICB9CgogICAgaWYgKGxpbmUubGVuZ3RoICYmIGxpbmUgIT09ICdcbicpIHJlc3VsdCArPSBpbmQ7CgogICAgcmVzdWx0ICs9IGxpbmU7CiAgfQoKICByZXR1cm4gcmVzdWx0Owp9CgpmdW5jdGlvbiBnZW5lcmF0ZU5leHRMaW5lKHN0YXRlLCBsZXZlbCkgewogIHJldHVybiAnXG4nICsgY29tbW9uLnJlcGVhdCgnICcsIHN0YXRlLmluZGVudCAqIGxldmVsKTsKfQoKZnVuY3Rpb24gdGVzdEltcGxpY2l0UmVzb2x2aW5nKHN0YXRlLCBzdHIpIHsKICB2YXIgaW5kZXgsIGxlbmd0aCwgdHlwZTsKCiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IHN0YXRlLmltcGxpY2l0VHlwZXMubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkgewogICAgdHlwZSA9IHN0YXRlLmltcGxpY2l0VHlwZXNbaW5kZXhdOwoKICAgIGlmICh0eXBlLnJlc29sdmUoc3RyKSkgewogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICB9CgogIHJldHVybiBmYWxzZTsKfQpmdW5jdGlvbiBpc1doaXRlc3BhY2UoYykgewogIHJldHVybiBjID09PSBDSEFSX1NQQUNFIHx8IGMgPT09IENIQVJfVEFCOwp9CmZ1bmN0aW9uIGlzUHJpbnRhYmxlKGMpIHsKICByZXR1cm4gIChjID49IDB4MDAwMjAgJiYgYyA8PSAweDAwMDA3RSkKICAgICAgfHwgKChjID49IDB4MDAwQTEgJiYgYyA8PSAweDAwRDdGRikgJiYgYyAhPT0gMHgyMDI4ICYmIGMgIT09IDB4MjAyOSkKICAgICAgfHwgKChjID49IDB4MEUwMDAgJiYgYyA8PSAweDAwRkZGRCkgJiYgYyAhPT0gMHhGRUZGIC8qIEJPTSAqLykKICAgICAgfHwgIChjID49IDB4MTAwMDAgJiYgYyA8PSAweDEwRkZGRik7Cn0KZnVuY3Rpb24gaXNQbGFpblNhZmUoYykgewogIHJldHVybiBpc1ByaW50YWJsZShjKSAmJiBjICE9PSAweEZFRkYKICAgICYmIGMgIT09IENIQVJfQ09NTUEKICAgICYmIGMgIT09IENIQVJfTEVGVF9TUVVBUkVfQlJBQ0tFVAogICAgJiYgYyAhPT0gQ0hBUl9SSUdIVF9TUVVBUkVfQlJBQ0tFVAogICAgJiYgYyAhPT0gQ0hBUl9MRUZUX0NVUkxZX0JSQUNLRVQKICAgICYmIGMgIT09IENIQVJfUklHSFRfQ1VSTFlfQlJBQ0tFVAogICAgJiYgYyAhPT0gQ0hBUl9DT0xPTgogICAgJiYgYyAhPT0gQ0hBUl9TSEFSUDsKfQpmdW5jdGlvbiBpc1BsYWluU2FmZUZpcnN0KGMpIHsKICByZXR1cm4gaXNQcmludGFibGUoYykgJiYgYyAhPT0gMHhGRUZGCiAgICAmJiAhaXNXaGl0ZXNwYWNlKGMpIC8vIC0gcy13aGl0ZQogICAgJiYgYyAhPT0gQ0hBUl9NSU5VUwogICAgJiYgYyAhPT0gQ0hBUl9RVUVTVElPTgogICAgJiYgYyAhPT0gQ0hBUl9DT0xPTgogICAgJiYgYyAhPT0gQ0hBUl9DT01NQQogICAgJiYgYyAhPT0gQ0hBUl9MRUZUX1NRVUFSRV9CUkFDS0VUCiAgICAmJiBjICE9PSBDSEFSX1JJR0hUX1NRVUFSRV9CUkFDS0VUCiAgICAmJiBjICE9PSBDSEFSX0xFRlRfQ1VSTFlfQlJBQ0tFVAogICAgJiYgYyAhPT0gQ0hBUl9SSUdIVF9DVVJMWV9CUkFDS0VUCiAgICAmJiBjICE9PSBDSEFSX1NIQVJQCiAgICAmJiBjICE9PSBDSEFSX0FNUEVSU0FORAogICAgJiYgYyAhPT0gQ0hBUl9BU1RFUklTSwogICAgJiYgYyAhPT0gQ0hBUl9FWENMQU1BVElPTgogICAgJiYgYyAhPT0gQ0hBUl9WRVJUSUNBTF9MSU5FCiAgICAmJiBjICE9PSBDSEFSX0dSRUFURVJfVEhBTgogICAgJiYgYyAhPT0gQ0hBUl9TSU5HTEVfUVVPVEUKICAgICYmIGMgIT09IENIQVJfRE9VQkxFX1FVT1RFCiAgICAmJiBjICE9PSBDSEFSX1BFUkNFTlQKICAgICYmIGMgIT09IENIQVJfQ09NTUVSQ0lBTF9BVAogICAgJiYgYyAhPT0gQ0hBUl9HUkFWRV9BQ0NFTlQ7Cn0KZnVuY3Rpb24gbmVlZEluZGVudEluZGljYXRvcihzdHJpbmcpIHsKICB2YXIgbGVhZGluZ1NwYWNlUmUgPSAvXlxuKiAvOwogIHJldHVybiBsZWFkaW5nU3BhY2VSZS50ZXN0KHN0cmluZyk7Cn0KCnZhciBTVFlMRV9QTEFJTiAgID0gMSwKICAgIFNUWUxFX1NJTkdMRSAgPSAyLAogICAgU1RZTEVfTElURVJBTCA9IDMsCiAgICBTVFlMRV9GT0xERUQgID0gNCwKICAgIFNUWUxFX0RPVUJMRSAgPSA1OwpmdW5jdGlvbiBjaG9vc2VTY2FsYXJTdHlsZShzdHJpbmcsIHNpbmdsZUxpbmVPbmx5LCBpbmRlbnRQZXJMZXZlbCwgbGluZVdpZHRoLCB0ZXN0QW1iaWd1b3VzVHlwZSkgewogIHZhciBpOwogIHZhciBjaGFyOwogIHZhciBoYXNMaW5lQnJlYWsgPSBmYWxzZTsKICB2YXIgaGFzRm9sZGFibGVMaW5lID0gZmFsc2U7IC8vIG9ubHkgY2hlY2tlZCBpZiBzaG91bGRUcmFja1dpZHRoCiAgdmFyIHNob3VsZFRyYWNrV2lkdGggPSBsaW5lV2lkdGggIT09IC0xOwogIHZhciBwcmV2aW91c0xpbmVCcmVhayA9IC0xOyAvLyBjb3VudCB0aGUgZmlyc3QgbGluZSBjb3JyZWN0bHkKICB2YXIgcGxhaW4gPSBpc1BsYWluU2FmZUZpcnN0KHN0cmluZy5jaGFyQ29kZUF0KDApKQogICAgICAgICAgJiYgIWlzV2hpdGVzcGFjZShzdHJpbmcuY2hhckNvZGVBdChzdHJpbmcubGVuZ3RoIC0gMSkpOwoKICBpZiAoc2luZ2xlTGluZU9ubHkpIHsKICAgIGZvciAoaSA9IDA7IGkgPCBzdHJpbmcubGVuZ3RoOyBpKyspIHsKICAgICAgY2hhciA9IHN0cmluZy5jaGFyQ29kZUF0KGkpOwogICAgICBpZiAoIWlzUHJpbnRhYmxlKGNoYXIpKSB7CiAgICAgICAgcmV0dXJuIFNUWUxFX0RPVUJMRTsKICAgICAgfQogICAgICBwbGFpbiA9IHBsYWluICYmIGlzUGxhaW5TYWZlKGNoYXIpOwogICAgfQogIH0gZWxzZSB7CiAgICBmb3IgKGkgPSAwOyBpIDwgc3RyaW5nLmxlbmd0aDsgaSsrKSB7CiAgICAgIGNoYXIgPSBzdHJpbmcuY2hhckNvZGVBdChpKTsKICAgICAgaWYgKGNoYXIgPT09IENIQVJfTElORV9GRUVEKSB7CiAgICAgICAgaGFzTGluZUJyZWFrID0gdHJ1ZTsKICAgICAgICBpZiAoc2hvdWxkVHJhY2tXaWR0aCkgewogICAgICAgICAgaGFzRm9sZGFibGVMaW5lID0gaGFzRm9sZGFibGVMaW5lIHx8CiAgICAgICAgICAgIChpIC0gcHJldmlvdXNMaW5lQnJlYWsgLSAxID4gbGluZVdpZHRoICYmCiAgICAgICAgICAgICBzdHJpbmdbcHJldmlvdXNMaW5lQnJlYWsgKyAxXSAhPT0gJyAnKTsKICAgICAgICAgIHByZXZpb3VzTGluZUJyZWFrID0gaTsKICAgICAgICB9CiAgICAgIH0gZWxzZSBpZiAoIWlzUHJpbnRhYmxlKGNoYXIpKSB7CiAgICAgICAgcmV0dXJuIFNUWUxFX0RPVUJMRTsKICAgICAgfQogICAgICBwbGFpbiA9IHBsYWluICYmIGlzUGxhaW5TYWZlKGNoYXIpOwogICAgfQogICAgaGFzRm9sZGFibGVMaW5lID0gaGFzRm9sZGFibGVMaW5lIHx8IChzaG91bGRUcmFja1dpZHRoICYmCiAgICAgIChpIC0gcHJldmlvdXNMaW5lQnJlYWsgLSAxID4gbGluZVdpZHRoICYmCiAgICAgICBzdHJpbmdbcHJldmlvdXNMaW5lQnJlYWsgKyAxXSAhPT0gJyAnKSk7CiAgfQogIGlmICghaGFzTGluZUJyZWFrICYmICFoYXNGb2xkYWJsZUxpbmUpIHsKICAgIHJldHVybiBwbGFpbiAmJiAhdGVzdEFtYmlndW91c1R5cGUoc3RyaW5nKQogICAgICA/IFNUWUxFX1BMQUlOIDogU1RZTEVfU0lOR0xFOwogIH0KICBpZiAoaW5kZW50UGVyTGV2ZWwgPiA5ICYmIG5lZWRJbmRlbnRJbmRpY2F0b3Ioc3RyaW5nKSkgewogICAgcmV0dXJuIFNUWUxFX0RPVUJMRTsKICB9CiAgcmV0dXJuIGhhc0ZvbGRhYmxlTGluZSA/IFNUWUxFX0ZPTERFRCA6IFNUWUxFX0xJVEVSQUw7Cn0KZnVuY3Rpb24gd3JpdGVTY2FsYXIoc3RhdGUsIHN0cmluZywgbGV2ZWwsIGlza2V5KSB7CiAgc3RhdGUuZHVtcCA9IChmdW5jdGlvbiAoKSB7CiAgICBpZiAoc3RyaW5nLmxlbmd0aCA9PT0gMCkgewogICAgICByZXR1cm4gIicnIjsKICAgIH0KICAgIGlmICghc3RhdGUubm9Db21wYXRNb2RlICYmCiAgICAgICAgREVQUkVDQVRFRF9CT09MRUFOU19TWU5UQVguaW5kZXhPZihzdHJpbmcpICE9PSAtMSkgewogICAgICByZXR1cm4gIiciICsgc3RyaW5nICsgIiciOwogICAgfQoKICAgIHZhciBpbmRlbnQgPSBzdGF0ZS5pbmRlbnQgKiBNYXRoLm1heCgxLCBsZXZlbCk7IC8vIG5vIDAtaW5kZW50IHNjYWxhcnMKICAgIHZhciBsaW5lV2lkdGggPSBzdGF0ZS5saW5lV2lkdGggPT09IC0xCiAgICAgID8gLTEgOiBNYXRoLm1heChNYXRoLm1pbihzdGF0ZS5saW5lV2lkdGgsIDQwKSwgc3RhdGUubGluZVdpZHRoIC0gaW5kZW50KTsKICAgIHZhciBzaW5nbGVMaW5lT25seSA9IGlza2V5CiAgICAgIHx8IChzdGF0ZS5mbG93TGV2ZWwgPiAtMSAmJiBsZXZlbCA+PSBzdGF0ZS5mbG93TGV2ZWwpOwogICAgZnVuY3Rpb24gdGVzdEFtYmlndWl0eShzdHJpbmcpIHsKICAgICAgcmV0dXJuIHRlc3RJbXBsaWNpdFJlc29sdmluZyhzdGF0ZSwgc3RyaW5nKTsKICAgIH0KCiAgICBzd2l0Y2ggKGNob29zZVNjYWxhclN0eWxlKHN0cmluZywgc2luZ2xlTGluZU9ubHksIHN0YXRlLmluZGVudCwgbGluZVdpZHRoLCB0ZXN0QW1iaWd1aXR5KSkgewogICAgICBjYXNlIFNUWUxFX1BMQUlOOgogICAgICAgIHJldHVybiBzdHJpbmc7CiAgICAgIGNhc2UgU1RZTEVfU0lOR0xFOgogICAgICAgIHJldHVybiAiJyIgKyBzdHJpbmcucmVwbGFjZSgvJy9nLCAiJyciKSArICInIjsKICAgICAgY2FzZSBTVFlMRV9MSVRFUkFMOgogICAgICAgIHJldHVybiAnfCcgKyBibG9ja0hlYWRlcihzdHJpbmcsIHN0YXRlLmluZGVudCkKICAgICAgICAgICsgZHJvcEVuZGluZ05ld2xpbmUoaW5kZW50U3RyaW5nKHN0cmluZywgaW5kZW50KSk7CiAgICAgIGNhc2UgU1RZTEVfRk9MREVEOgogICAgICAgIHJldHVybiAnPicgKyBibG9ja0hlYWRlcihzdHJpbmcsIHN0YXRlLmluZGVudCkKICAgICAgICAgICsgZHJvcEVuZGluZ05ld2xpbmUoaW5kZW50U3RyaW5nKGZvbGRTdHJpbmcoc3RyaW5nLCBsaW5lV2lkdGgpLCBpbmRlbnQpKTsKICAgICAgY2FzZSBTVFlMRV9ET1VCTEU6CiAgICAgICAgcmV0dXJuICciJyArIGVzY2FwZVN0cmluZyhzdHJpbmcsIGxpbmVXaWR0aCkgKyAnIic7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ2ltcG9zc2libGUgZXJyb3I6IGludmFsaWQgc2NhbGFyIHN0eWxlJyk7CiAgICB9CiAgfSgpKTsKfQpmdW5jdGlvbiBibG9ja0hlYWRlcihzdHJpbmcsIGluZGVudFBlckxldmVsKSB7CiAgdmFyIGluZGVudEluZGljYXRvciA9IG5lZWRJbmRlbnRJbmRpY2F0b3Ioc3RyaW5nKSA/IFN0cmluZyhpbmRlbnRQZXJMZXZlbCkgOiAnJzsKICB2YXIgY2xpcCA9ICAgICAgICAgIHN0cmluZ1tzdHJpbmcubGVuZ3RoIC0gMV0gPT09ICdcbic7CiAgdmFyIGtlZXAgPSBjbGlwICYmIChzdHJpbmdbc3RyaW5nLmxlbmd0aCAtIDJdID09PSAnXG4nIHx8IHN0cmluZyA9PT0gJ1xuJyk7CiAgdmFyIGNob21wID0ga2VlcCA/ICcrJyA6IChjbGlwID8gJycgOiAnLScpOwoKICByZXR1cm4gaW5kZW50SW5kaWNhdG9yICsgY2hvbXAgKyAnXG4nOwp9CmZ1bmN0aW9uIGRyb3BFbmRpbmdOZXdsaW5lKHN0cmluZykgewogIHJldHVybiBzdHJpbmdbc3RyaW5nLmxlbmd0aCAtIDFdID09PSAnXG4nID8gc3RyaW5nLnNsaWNlKDAsIC0xKSA6IHN0cmluZzsKfQpmdW5jdGlvbiBmb2xkU3RyaW5nKHN0cmluZywgd2lkdGgpIHsKICB2YXIgbGluZVJlID0gLyhcbispKFteXG5dKikvZzsKICB2YXIgcmVzdWx0ID0gKGZ1bmN0aW9uICgpIHsKICAgIHZhciBuZXh0TEYgPSBzdHJpbmcuaW5kZXhPZignXG4nKTsKICAgIG5leHRMRiA9IG5leHRMRiAhPT0gLTEgPyBuZXh0TEYgOiBzdHJpbmcubGVuZ3RoOwogICAgbGluZVJlLmxhc3RJbmRleCA9IG5leHRMRjsKICAgIHJldHVybiBmb2xkTGluZShzdHJpbmcuc2xpY2UoMCwgbmV4dExGKSwgd2lkdGgpOwogIH0oKSk7CiAgdmFyIHByZXZNb3JlSW5kZW50ZWQgPSBzdHJpbmdbMF0gPT09ICdcbicgfHwgc3RyaW5nWzBdID09PSAnICc7CiAgdmFyIG1vcmVJbmRlbnRlZDsKICB2YXIgbWF0Y2g7CiAgd2hpbGUgKChtYXRjaCA9IGxpbmVSZS5leGVjKHN0cmluZykpKSB7CiAgICB2YXIgcHJlZml4ID0gbWF0Y2hbMV0sIGxpbmUgPSBtYXRjaFsyXTsKICAgIG1vcmVJbmRlbnRlZCA9IChsaW5lWzBdID09PSAnICcpOwogICAgcmVzdWx0ICs9IHByZWZpeAogICAgICArICghcHJldk1vcmVJbmRlbnRlZCAmJiAhbW9yZUluZGVudGVkICYmIGxpbmUgIT09ICcnCiAgICAgICAgPyAnXG4nIDogJycpCiAgICAgICsgZm9sZExpbmUobGluZSwgd2lkdGgpOwogICAgcHJldk1vcmVJbmRlbnRlZCA9IG1vcmVJbmRlbnRlZDsKICB9CgogIHJldHVybiByZXN1bHQ7Cn0KZnVuY3Rpb24gZm9sZExpbmUobGluZSwgd2lkdGgpIHsKICBpZiAobGluZSA9PT0gJycgfHwgbGluZVswXSA9PT0gJyAnKSByZXR1cm4gbGluZTsKICB2YXIgYnJlYWtSZSA9IC8gW14gXS9nOyAvLyBub3RlOiB0aGUgbWF0Y2ggaW5kZXggd2lsbCBhbHdheXMgYmUgPD0gbGVuZ3RoLTIuCiAgdmFyIG1hdGNoOwogIHZhciBzdGFydCA9IDAsIGVuZCwgY3VyciA9IDAsIG5leHQgPSAwOwogIHZhciByZXN1bHQgPSAnJzsKICB3aGlsZSAoKG1hdGNoID0gYnJlYWtSZS5leGVjKGxpbmUpKSkgewogICAgbmV4dCA9IG1hdGNoLmluZGV4OwogICAgaWYgKG5leHQgLSBzdGFydCA+IHdpZHRoKSB7CiAgICAgIGVuZCA9IChjdXJyID4gc3RhcnQpID8gY3VyciA6IG5leHQ7IC8vIGRlcml2ZSBlbmQgPD0gbGVuZ3RoLTIKICAgICAgcmVzdWx0ICs9ICdcbicgKyBsaW5lLnNsaWNlKHN0YXJ0LCBlbmQpOwogICAgICBzdGFydCA9IGVuZCArIDE7ICAgICAgICAgICAgICAgICAgICAvLyBkZXJpdmUgc3RhcnQgPD0gbGVuZ3RoLTEKICAgIH0KICAgIGN1cnIgPSBuZXh0OwogIH0KICByZXN1bHQgKz0gJ1xuJzsKICBpZiAobGluZS5sZW5ndGggLSBzdGFydCA+IHdpZHRoICYmIGN1cnIgPiBzdGFydCkgewogICAgcmVzdWx0ICs9IGxpbmUuc2xpY2Uoc3RhcnQsIGN1cnIpICsgJ1xuJyArIGxpbmUuc2xpY2UoY3VyciArIDEpOwogIH0gZWxzZSB7CiAgICByZXN1bHQgKz0gbGluZS5zbGljZShzdGFydCk7CiAgfQoKICByZXR1cm4gcmVzdWx0LnNsaWNlKDEpOyAvLyBkcm9wIGV4dHJhIFxuIGpvaW5lcgp9CmZ1bmN0aW9uIGVzY2FwZVN0cmluZyhzdHJpbmcpIHsKICB2YXIgcmVzdWx0ID0gJyc7CiAgdmFyIGNoYXIsIG5leHRDaGFyOwogIHZhciBlc2NhcGVTZXE7CgogIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyaW5nLmxlbmd0aDsgaSsrKSB7CiAgICBjaGFyID0gc3RyaW5nLmNoYXJDb2RlQXQoaSk7CiAgICBpZiAoY2hhciA+PSAweEQ4MDAgJiYgY2hhciA8PSAweERCRkYvKiBoaWdoIHN1cnJvZ2F0ZSAqLykgewogICAgICBuZXh0Q2hhciA9IHN0cmluZy5jaGFyQ29kZUF0KGkgKyAxKTsKICAgICAgaWYgKG5leHRDaGFyID49IDB4REMwMCAmJiBuZXh0Q2hhciA8PSAweERGRkYvKiBsb3cgc3Vycm9nYXRlICovKSB7CiAgICAgICAgcmVzdWx0ICs9IGVuY29kZUhleCgoY2hhciAtIDB4RDgwMCkgKiAweDQwMCArIG5leHRDaGFyIC0gMHhEQzAwICsgMHgxMDAwMCk7CiAgICAgICAgaSsrOyBjb250aW51ZTsKICAgICAgfQogICAgfQogICAgZXNjYXBlU2VxID0gRVNDQVBFX1NFUVVFTkNFU1tjaGFyXTsKICAgIHJlc3VsdCArPSAhZXNjYXBlU2VxICYmIGlzUHJpbnRhYmxlKGNoYXIpCiAgICAgID8gc3RyaW5nW2ldCiAgICAgIDogZXNjYXBlU2VxIHx8IGVuY29kZUhleChjaGFyKTsKICB9CgogIHJldHVybiByZXN1bHQ7Cn0KCmZ1bmN0aW9uIHdyaXRlRmxvd1NlcXVlbmNlKHN0YXRlLCBsZXZlbCwgb2JqZWN0KSB7CiAgdmFyIF9yZXN1bHQgPSAnJywKICAgICAgX3RhZyAgICA9IHN0YXRlLnRhZywKICAgICAgaW5kZXgsCiAgICAgIGxlbmd0aDsKCiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IG9iamVjdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7CiAgICBpZiAod3JpdGVOb2RlKHN0YXRlLCBsZXZlbCwgb2JqZWN0W2luZGV4XSwgZmFsc2UsIGZhbHNlKSkgewogICAgICBpZiAoaW5kZXggIT09IDApIF9yZXN1bHQgKz0gJywnICsgKCFzdGF0ZS5jb25kZW5zZUZsb3cgPyAnICcgOiAnJyk7CiAgICAgIF9yZXN1bHQgKz0gc3RhdGUuZHVtcDsKICAgIH0KICB9CgogIHN0YXRlLnRhZyA9IF90YWc7CiAgc3RhdGUuZHVtcCA9ICdbJyArIF9yZXN1bHQgKyAnXSc7Cn0KCmZ1bmN0aW9uIHdyaXRlQmxvY2tTZXF1ZW5jZShzdGF0ZSwgbGV2ZWwsIG9iamVjdCwgY29tcGFjdCkgewogIHZhciBfcmVzdWx0ID0gJycsCiAgICAgIF90YWcgICAgPSBzdGF0ZS50YWcsCiAgICAgIGluZGV4LAogICAgICBsZW5ndGg7CgogIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkgewogICAgaWYgKHdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwgKyAxLCBvYmplY3RbaW5kZXhdLCB0cnVlLCB0cnVlKSkgewogICAgICBpZiAoIWNvbXBhY3QgfHwgaW5kZXggIT09IDApIHsKICAgICAgICBfcmVzdWx0ICs9IGdlbmVyYXRlTmV4dExpbmUoc3RhdGUsIGxldmVsKTsKICAgICAgfQoKICAgICAgaWYgKHN0YXRlLmR1bXAgJiYgQ0hBUl9MSU5FX0ZFRUQgPT09IHN0YXRlLmR1bXAuY2hhckNvZGVBdCgwKSkgewogICAgICAgIF9yZXN1bHQgKz0gJy0nOwogICAgICB9IGVsc2UgewogICAgICAgIF9yZXN1bHQgKz0gJy0gJzsKICAgICAgfQoKICAgICAgX3Jlc3VsdCArPSBzdGF0ZS5kdW1wOwogICAgfQogIH0KCiAgc3RhdGUudGFnID0gX3RhZzsKICBzdGF0ZS5kdW1wID0gX3Jlc3VsdCB8fCAnW10nOyAvLyBFbXB0eSBzZXF1ZW5jZSBpZiBubyB2YWxpZCB2YWx1ZXMuCn0KCmZ1bmN0aW9uIHdyaXRlRmxvd01hcHBpbmcoc3RhdGUsIGxldmVsLCBvYmplY3QpIHsKICB2YXIgX3Jlc3VsdCAgICAgICA9ICcnLAogICAgICBfdGFnICAgICAgICAgID0gc3RhdGUudGFnLAogICAgICBvYmplY3RLZXlMaXN0ID0gT2JqZWN0LmtleXMob2JqZWN0KSwKICAgICAgaW5kZXgsCiAgICAgIGxlbmd0aCwKICAgICAgb2JqZWN0S2V5LAogICAgICBvYmplY3RWYWx1ZSwKICAgICAgcGFpckJ1ZmZlcjsKCiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IG9iamVjdEtleUxpc3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkgewogICAgcGFpckJ1ZmZlciA9IHN0YXRlLmNvbmRlbnNlRmxvdyA/ICciJyA6ICcnOwoKICAgIGlmIChpbmRleCAhPT0gMCkgcGFpckJ1ZmZlciArPSAnLCAnOwoKICAgIG9iamVjdEtleSA9IG9iamVjdEtleUxpc3RbaW5kZXhdOwogICAgb2JqZWN0VmFsdWUgPSBvYmplY3Rbb2JqZWN0S2V5XTsKCiAgICBpZiAoIXdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwsIG9iamVjdEtleSwgZmFsc2UsIGZhbHNlKSkgewogICAgICBjb250aW51ZTsgLy8gU2tpcCB0aGlzIHBhaXIgYmVjYXVzZSBvZiBpbnZhbGlkIGtleTsKICAgIH0KCiAgICBpZiAoc3RhdGUuZHVtcC5sZW5ndGggPiAxMDI0KSBwYWlyQnVmZmVyICs9ICc/ICc7CgogICAgcGFpckJ1ZmZlciArPSBzdGF0ZS5kdW1wICsgKHN0YXRlLmNvbmRlbnNlRmxvdyA/ICciJyA6ICcnKSArICc6JyArIChzdGF0ZS5jb25kZW5zZUZsb3cgPyAnJyA6ICcgJyk7CgogICAgaWYgKCF3cml0ZU5vZGUoc3RhdGUsIGxldmVsLCBvYmplY3RWYWx1ZSwgZmFsc2UsIGZhbHNlKSkgewogICAgICBjb250aW51ZTsgLy8gU2tpcCB0aGlzIHBhaXIgYmVjYXVzZSBvZiBpbnZhbGlkIHZhbHVlLgogICAgfQoKICAgIHBhaXJCdWZmZXIgKz0gc3RhdGUuZHVtcDsKICAgIF9yZXN1bHQgKz0gcGFpckJ1ZmZlcjsKICB9CgogIHN0YXRlLnRhZyA9IF90YWc7CiAgc3RhdGUuZHVtcCA9ICd7JyArIF9yZXN1bHQgKyAnfSc7Cn0KCmZ1bmN0aW9uIHdyaXRlQmxvY2tNYXBwaW5nKHN0YXRlLCBsZXZlbCwgb2JqZWN0LCBjb21wYWN0KSB7CiAgdmFyIF9yZXN1bHQgICAgICAgPSAnJywKICAgICAgX3RhZyAgICAgICAgICA9IHN0YXRlLnRhZywKICAgICAgb2JqZWN0S2V5TGlzdCA9IE9iamVjdC5rZXlzKG9iamVjdCksCiAgICAgIGluZGV4LAogICAgICBsZW5ndGgsCiAgICAgIG9iamVjdEtleSwKICAgICAgb2JqZWN0VmFsdWUsCiAgICAgIGV4cGxpY2l0UGFpciwKICAgICAgcGFpckJ1ZmZlcjsKICBpZiAoc3RhdGUuc29ydEtleXMgPT09IHRydWUpIHsKICAgIG9iamVjdEtleUxpc3Quc29ydCgpOwogIH0gZWxzZSBpZiAodHlwZW9mIHN0YXRlLnNvcnRLZXlzID09PSAnZnVuY3Rpb24nKSB7CiAgICBvYmplY3RLZXlMaXN0LnNvcnQoc3RhdGUuc29ydEtleXMpOwogIH0gZWxzZSBpZiAoc3RhdGUuc29ydEtleXMpIHsKICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdzb3J0S2V5cyBtdXN0IGJlIGEgYm9vbGVhbiBvciBhIGZ1bmN0aW9uJyk7CiAgfQoKICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gb2JqZWN0S2V5TGlzdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7CiAgICBwYWlyQnVmZmVyID0gJyc7CgogICAgaWYgKCFjb21wYWN0IHx8IGluZGV4ICE9PSAwKSB7CiAgICAgIHBhaXJCdWZmZXIgKz0gZ2VuZXJhdGVOZXh0TGluZShzdGF0ZSwgbGV2ZWwpOwogICAgfQoKICAgIG9iamVjdEtleSA9IG9iamVjdEtleUxpc3RbaW5kZXhdOwogICAgb2JqZWN0VmFsdWUgPSBvYmplY3Rbb2JqZWN0S2V5XTsKCiAgICBpZiAoIXdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwgKyAxLCBvYmplY3RLZXksIHRydWUsIHRydWUsIHRydWUpKSB7CiAgICAgIGNvbnRpbnVlOyAvLyBTa2lwIHRoaXMgcGFpciBiZWNhdXNlIG9mIGludmFsaWQga2V5LgogICAgfQoKICAgIGV4cGxpY2l0UGFpciA9IChzdGF0ZS50YWcgIT09IG51bGwgJiYgc3RhdGUudGFnICE9PSAnPycpIHx8CiAgICAgICAgICAgICAgICAgICAoc3RhdGUuZHVtcCAmJiBzdGF0ZS5kdW1wLmxlbmd0aCA+IDEwMjQpOwoKICAgIGlmIChleHBsaWNpdFBhaXIpIHsKICAgICAgaWYgKHN0YXRlLmR1bXAgJiYgQ0hBUl9MSU5FX0ZFRUQgPT09IHN0YXRlLmR1bXAuY2hhckNvZGVBdCgwKSkgewogICAgICAgIHBhaXJCdWZmZXIgKz0gJz8nOwogICAgICB9IGVsc2UgewogICAgICAgIHBhaXJCdWZmZXIgKz0gJz8gJzsKICAgICAgfQogICAgfQoKICAgIHBhaXJCdWZmZXIgKz0gc3RhdGUuZHVtcDsKCiAgICBpZiAoZXhwbGljaXRQYWlyKSB7CiAgICAgIHBhaXJCdWZmZXIgKz0gZ2VuZXJhdGVOZXh0TGluZShzdGF0ZSwgbGV2ZWwpOwogICAgfQoKICAgIGlmICghd3JpdGVOb2RlKHN0YXRlLCBsZXZlbCArIDEsIG9iamVjdFZhbHVlLCB0cnVlLCBleHBsaWNpdFBhaXIpKSB7CiAgICAgIGNvbnRpbnVlOyAvLyBTa2lwIHRoaXMgcGFpciBiZWNhdXNlIG9mIGludmFsaWQgdmFsdWUuCiAgICB9CgogICAgaWYgKHN0YXRlLmR1bXAgJiYgQ0hBUl9MSU5FX0ZFRUQgPT09IHN0YXRlLmR1bXAuY2hhckNvZGVBdCgwKSkgewogICAgICBwYWlyQnVmZmVyICs9ICc6JzsKICAgIH0gZWxzZSB7CiAgICAgIHBhaXJCdWZmZXIgKz0gJzogJzsKICAgIH0KCiAgICBwYWlyQnVmZmVyICs9IHN0YXRlLmR1bXA7CiAgICBfcmVzdWx0ICs9IHBhaXJCdWZmZXI7CiAgfQoKICBzdGF0ZS50YWcgPSBfdGFnOwogIHN0YXRlLmR1bXAgPSBfcmVzdWx0IHx8ICd7fSc7IC8vIEVtcHR5IG1hcHBpbmcgaWYgbm8gdmFsaWQgcGFpcnMuCn0KCmZ1bmN0aW9uIGRldGVjdFR5cGUoc3RhdGUsIG9iamVjdCwgZXhwbGljaXQpIHsKICB2YXIgX3Jlc3VsdCwgdHlwZUxpc3QsIGluZGV4LCBsZW5ndGgsIHR5cGUsIHN0eWxlOwoKICB0eXBlTGlzdCA9IGV4cGxpY2l0ID8gc3RhdGUuZXhwbGljaXRUeXBlcyA6IHN0YXRlLmltcGxpY2l0VHlwZXM7CgogIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSB0eXBlTGlzdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7CiAgICB0eXBlID0gdHlwZUxpc3RbaW5kZXhdOwoKICAgIGlmICgodHlwZS5pbnN0YW5jZU9mICB8fCB0eXBlLnByZWRpY2F0ZSkgJiYKICAgICAgICAoIXR5cGUuaW5zdGFuY2VPZiB8fCAoKHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnKSAmJiAob2JqZWN0IGluc3RhbmNlb2YgdHlwZS5pbnN0YW5jZU9mKSkpICYmCiAgICAgICAgKCF0eXBlLnByZWRpY2F0ZSAgfHwgdHlwZS5wcmVkaWNhdGUob2JqZWN0KSkpIHsKCiAgICAgIHN0YXRlLnRhZyA9IGV4cGxpY2l0ID8gdHlwZS50YWcgOiAnPyc7CgogICAgICBpZiAodHlwZS5yZXByZXNlbnQpIHsKICAgICAgICBzdHlsZSA9IHN0YXRlLnN0eWxlTWFwW3R5cGUudGFnXSB8fCB0eXBlLmRlZmF1bHRTdHlsZTsKCiAgICAgICAgaWYgKF90b1N0cmluZy5jYWxsKHR5cGUucmVwcmVzZW50KSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJykgewogICAgICAgICAgX3Jlc3VsdCA9IHR5cGUucmVwcmVzZW50KG9iamVjdCwgc3R5bGUpOwogICAgICAgIH0gZWxzZSBpZiAoX2hhc093blByb3BlcnR5LmNhbGwodHlwZS5yZXByZXNlbnQsIHN0eWxlKSkgewogICAgICAgICAgX3Jlc3VsdCA9IHR5cGUucmVwcmVzZW50W3N0eWxlXShvYmplY3QsIHN0eWxlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJyE8JyArIHR5cGUudGFnICsgJz4gdGFnIHJlc29sdmVyIGFjY2VwdHMgbm90ICInICsgc3R5bGUgKyAnIiBzdHlsZScpOwogICAgICAgIH0KCiAgICAgICAgc3RhdGUuZHVtcCA9IF9yZXN1bHQ7CiAgICAgIH0KCiAgICAgIHJldHVybiB0cnVlOwogICAgfQogIH0KCiAgcmV0dXJuIGZhbHNlOwp9CmZ1bmN0aW9uIHdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwsIG9iamVjdCwgYmxvY2ssIGNvbXBhY3QsIGlza2V5KSB7CiAgc3RhdGUudGFnID0gbnVsbDsKICBzdGF0ZS5kdW1wID0gb2JqZWN0OwoKICBpZiAoIWRldGVjdFR5cGUoc3RhdGUsIG9iamVjdCwgZmFsc2UpKSB7CiAgICBkZXRlY3RUeXBlKHN0YXRlLCBvYmplY3QsIHRydWUpOwogIH0KCiAgdmFyIHR5cGUgPSBfdG9TdHJpbmcuY2FsbChzdGF0ZS5kdW1wKTsKCiAgaWYgKGJsb2NrKSB7CiAgICBibG9jayA9IChzdGF0ZS5mbG93TGV2ZWwgPCAwIHx8IHN0YXRlLmZsb3dMZXZlbCA+IGxldmVsKTsKICB9CgogIHZhciBvYmplY3RPckFycmF5ID0gdHlwZSA9PT0gJ1tvYmplY3QgT2JqZWN0XScgfHwgdHlwZSA9PT0gJ1tvYmplY3QgQXJyYXldJywKICAgICAgZHVwbGljYXRlSW5kZXgsCiAgICAgIGR1cGxpY2F0ZTsKCiAgaWYgKG9iamVjdE9yQXJyYXkpIHsKICAgIGR1cGxpY2F0ZUluZGV4ID0gc3RhdGUuZHVwbGljYXRlcy5pbmRleE9mKG9iamVjdCk7CiAgICBkdXBsaWNhdGUgPSBkdXBsaWNhdGVJbmRleCAhPT0gLTE7CiAgfQoKICBpZiAoKHN0YXRlLnRhZyAhPT0gbnVsbCAmJiBzdGF0ZS50YWcgIT09ICc/JykgfHwgZHVwbGljYXRlIHx8IChzdGF0ZS5pbmRlbnQgIT09IDIgJiYgbGV2ZWwgPiAwKSkgewogICAgY29tcGFjdCA9IGZhbHNlOwogIH0KCiAgaWYgKGR1cGxpY2F0ZSAmJiBzdGF0ZS51c2VkRHVwbGljYXRlc1tkdXBsaWNhdGVJbmRleF0pIHsKICAgIHN0YXRlLmR1bXAgPSAnKnJlZl8nICsgZHVwbGljYXRlSW5kZXg7CiAgfSBlbHNlIHsKICAgIGlmIChvYmplY3RPckFycmF5ICYmIGR1cGxpY2F0ZSAmJiAhc3RhdGUudXNlZER1cGxpY2F0ZXNbZHVwbGljYXRlSW5kZXhdKSB7CiAgICAgIHN0YXRlLnVzZWREdXBsaWNhdGVzW2R1cGxpY2F0ZUluZGV4XSA9IHRydWU7CiAgICB9CiAgICBpZiAodHlwZSA9PT0gJ1tvYmplY3QgT2JqZWN0XScpIHsKICAgICAgaWYgKGJsb2NrICYmIChPYmplY3Qua2V5cyhzdGF0ZS5kdW1wKS5sZW5ndGggIT09IDApKSB7CiAgICAgICAgd3JpdGVCbG9ja01hcHBpbmcoc3RhdGUsIGxldmVsLCBzdGF0ZS5kdW1wLCBjb21wYWN0KTsKICAgICAgICBpZiAoZHVwbGljYXRlKSB7CiAgICAgICAgICBzdGF0ZS5kdW1wID0gJyZyZWZfJyArIGR1cGxpY2F0ZUluZGV4ICsgc3RhdGUuZHVtcDsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgd3JpdGVGbG93TWFwcGluZyhzdGF0ZSwgbGV2ZWwsIHN0YXRlLmR1bXApOwogICAgICAgIGlmIChkdXBsaWNhdGUpIHsKICAgICAgICAgIHN0YXRlLmR1bXAgPSAnJnJlZl8nICsgZHVwbGljYXRlSW5kZXggKyAnICcgKyBzdGF0ZS5kdW1wOwogICAgICAgIH0KICAgICAgfQogICAgfSBlbHNlIGlmICh0eXBlID09PSAnW29iamVjdCBBcnJheV0nKSB7CiAgICAgIHZhciBhcnJheUxldmVsID0gKHN0YXRlLm5vQXJyYXlJbmRlbnQgJiYgKGxldmVsID4gMCkpID8gbGV2ZWwgLSAxIDogbGV2ZWw7CiAgICAgIGlmIChibG9jayAmJiAoc3RhdGUuZHVtcC5sZW5ndGggIT09IDApKSB7CiAgICAgICAgd3JpdGVCbG9ja1NlcXVlbmNlKHN0YXRlLCBhcnJheUxldmVsLCBzdGF0ZS5kdW1wLCBjb21wYWN0KTsKICAgICAgICBpZiAoZHVwbGljYXRlKSB7CiAgICAgICAgICBzdGF0ZS5kdW1wID0gJyZyZWZfJyArIGR1cGxpY2F0ZUluZGV4ICsgc3RhdGUuZHVtcDsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgd3JpdGVGbG93U2VxdWVuY2Uoc3RhdGUsIGFycmF5TGV2ZWwsIHN0YXRlLmR1bXApOwogICAgICAgIGlmIChkdXBsaWNhdGUpIHsKICAgICAgICAgIHN0YXRlLmR1bXAgPSAnJnJlZl8nICsgZHVwbGljYXRlSW5kZXggKyAnICcgKyBzdGF0ZS5kdW1wOwogICAgICAgIH0KICAgICAgfQogICAgfSBlbHNlIGlmICh0eXBlID09PSAnW29iamVjdCBTdHJpbmddJykgewogICAgICBpZiAoc3RhdGUudGFnICE9PSAnPycpIHsKICAgICAgICB3cml0ZVNjYWxhcihzdGF0ZSwgc3RhdGUuZHVtcCwgbGV2ZWwsIGlza2V5KTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgaWYgKHN0YXRlLnNraXBJbnZhbGlkKSByZXR1cm4gZmFsc2U7CiAgICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCd1bmFjY2VwdGFibGUga2luZCBvZiBhbiBvYmplY3QgdG8gZHVtcCAnICsgdHlwZSk7CiAgICB9CgogICAgaWYgKHN0YXRlLnRhZyAhPT0gbnVsbCAmJiBzdGF0ZS50YWcgIT09ICc/JykgewogICAgICBzdGF0ZS5kdW1wID0gJyE8JyArIHN0YXRlLnRhZyArICc+ICcgKyBzdGF0ZS5kdW1wOwogICAgfQogIH0KCiAgcmV0dXJuIHRydWU7Cn0KCmZ1bmN0aW9uIGdldER1cGxpY2F0ZVJlZmVyZW5jZXMob2JqZWN0LCBzdGF0ZSkgewogIHZhciBvYmplY3RzID0gW10sCiAgICAgIGR1cGxpY2F0ZXNJbmRleGVzID0gW10sCiAgICAgIGluZGV4LAogICAgICBsZW5ndGg7CgogIGluc3BlY3ROb2RlKG9iamVjdCwgb2JqZWN0cywgZHVwbGljYXRlc0luZGV4ZXMpOwoKICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gZHVwbGljYXRlc0luZGV4ZXMubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkgewogICAgc3RhdGUuZHVwbGljYXRlcy5wdXNoKG9iamVjdHNbZHVwbGljYXRlc0luZGV4ZXNbaW5kZXhdXSk7CiAgfQogIHN0YXRlLnVzZWREdXBsaWNhdGVzID0gbmV3IEFycmF5KGxlbmd0aCk7Cn0KCmZ1bmN0aW9uIGluc3BlY3ROb2RlKG9iamVjdCwgb2JqZWN0cywgZHVwbGljYXRlc0luZGV4ZXMpIHsKICB2YXIgb2JqZWN0S2V5TGlzdCwKICAgICAgaW5kZXgsCiAgICAgIGxlbmd0aDsKCiAgaWYgKG9iamVjdCAhPT0gbnVsbCAmJiB0eXBlb2Ygb2JqZWN0ID09PSAnb2JqZWN0JykgewogICAgaW5kZXggPSBvYmplY3RzLmluZGV4T2Yob2JqZWN0KTsKICAgIGlmIChpbmRleCAhPT0gLTEpIHsKICAgICAgaWYgKGR1cGxpY2F0ZXNJbmRleGVzLmluZGV4T2YoaW5kZXgpID09PSAtMSkgewogICAgICAgIGR1cGxpY2F0ZXNJbmRleGVzLnB1c2goaW5kZXgpOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBvYmplY3RzLnB1c2gob2JqZWN0KTsKCiAgICAgIGlmIChBcnJheS5pc0FycmF5KG9iamVjdCkpIHsKICAgICAgICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gb2JqZWN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHsKICAgICAgICAgIGluc3BlY3ROb2RlKG9iamVjdFtpbmRleF0sIG9iamVjdHMsIGR1cGxpY2F0ZXNJbmRleGVzKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgb2JqZWN0S2V5TGlzdCA9IE9iamVjdC5rZXlzKG9iamVjdCk7CgogICAgICAgIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3RLZXlMaXN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHsKICAgICAgICAgIGluc3BlY3ROb2RlKG9iamVjdFtvYmplY3RLZXlMaXN0W2luZGV4XV0sIG9iamVjdHMsIGR1cGxpY2F0ZXNJbmRleGVzKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9Cn0KCmZ1bmN0aW9uIGR1bXAoaW5wdXQsIG9wdGlvbnMpIHsKICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKCiAgdmFyIHN0YXRlID0gbmV3IFN0YXRlKG9wdGlvbnMpOwoKICBpZiAoIXN0YXRlLm5vUmVmcykgZ2V0RHVwbGljYXRlUmVmZXJlbmNlcyhpbnB1dCwgc3RhdGUpOwoKICBpZiAod3JpdGVOb2RlKHN0YXRlLCAwLCBpbnB1dCwgdHJ1ZSwgdHJ1ZSkpIHJldHVybiBzdGF0ZS5kdW1wICsgJ1xuJzsKCiAgcmV0dXJuICcnOwp9CgpmdW5jdGlvbiBzYWZlRHVtcChpbnB1dCwgb3B0aW9ucykgewogIHJldHVybiBkdW1wKGlucHV0LCBjb21tb24uZXh0ZW5kKHsgc2NoZW1hOiBERUZBVUxUX1NBRkVfU0NIRU1BIH0sIG9wdGlvbnMpKTsKfQoKbW9kdWxlLmV4cG9ydHMuZHVtcCAgICAgPSBkdW1wOwptb2R1bGUuZXhwb3J0cy5zYWZlRHVtcCA9IHNhZmVEdW1wOwoKfSx7Ii4vY29tbW9uIjo1LCIuL2V4Y2VwdGlvbiI6NywiLi9zY2hlbWEvZGVmYXVsdF9mdWxsIjoxMiwiLi9zY2hlbWEvZGVmYXVsdF9zYWZlIjoxM31dLDc6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7CgpmdW5jdGlvbiBZQU1MRXhjZXB0aW9uKHJlYXNvbiwgbWFyaykgewogIEVycm9yLmNhbGwodGhpcyk7CgogIHRoaXMubmFtZSA9ICdZQU1MRXhjZXB0aW9uJzsKICB0aGlzLnJlYXNvbiA9IHJlYXNvbjsKICB0aGlzLm1hcmsgPSBtYXJrOwogIHRoaXMubWVzc2FnZSA9ICh0aGlzLnJlYXNvbiB8fCAnKHVua25vd24gcmVhc29uKScpICsgKHRoaXMubWFyayA/ICcgJyArIHRoaXMubWFyay50b1N0cmluZygpIDogJycpOwogIGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSkgewogICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgdGhpcy5jb25zdHJ1Y3Rvcik7CiAgfSBlbHNlIHsKICAgIHRoaXMuc3RhY2sgPSAobmV3IEVycm9yKCkpLnN0YWNrIHx8ICcnOwogIH0KfQpZQU1MRXhjZXB0aW9uLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoRXJyb3IucHJvdG90eXBlKTsKWUFNTEV4Y2VwdGlvbi5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBZQU1MRXhjZXB0aW9uOwoKCllBTUxFeGNlcHRpb24ucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoY29tcGFjdCkgewogIHZhciByZXN1bHQgPSB0aGlzLm5hbWUgKyAnOiAnOwoKICByZXN1bHQgKz0gdGhpcy5yZWFzb24gfHwgJyh1bmtub3duIHJlYXNvbiknOwoKICBpZiAoIWNvbXBhY3QgJiYgdGhpcy5tYXJrKSB7CiAgICByZXN1bHQgKz0gJyAnICsgdGhpcy5tYXJrLnRvU3RyaW5nKCk7CiAgfQoKICByZXR1cm4gcmVzdWx0Owp9OwoKCm1vZHVsZS5leHBvcnRzID0gWUFNTEV4Y2VwdGlvbjsKCn0se31dLDg6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7Cgp2YXIgY29tbW9uICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vY29tbW9uJyk7CnZhciBZQU1MRXhjZXB0aW9uICAgICAgID0gcmVxdWlyZSgnLi9leGNlcHRpb24nKTsKdmFyIE1hcmsgICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL21hcmsnKTsKdmFyIERFRkFVTFRfU0FGRV9TQ0hFTUEgPSByZXF1aXJlKCcuL3NjaGVtYS9kZWZhdWx0X3NhZmUnKTsKdmFyIERFRkFVTFRfRlVMTF9TQ0hFTUEgPSByZXF1aXJlKCcuL3NjaGVtYS9kZWZhdWx0X2Z1bGwnKTsKCgp2YXIgX2hhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTsKCgp2YXIgQ09OVEVYVF9GTE9XX0lOICAgPSAxOwp2YXIgQ09OVEVYVF9GTE9XX09VVCAgPSAyOwp2YXIgQ09OVEVYVF9CTE9DS19JTiAgPSAzOwp2YXIgQ09OVEVYVF9CTE9DS19PVVQgPSA0OwoKCnZhciBDSE9NUElOR19DTElQICA9IDE7CnZhciBDSE9NUElOR19TVFJJUCA9IDI7CnZhciBDSE9NUElOR19LRUVQICA9IDM7CgoKdmFyIFBBVFRFUk5fTk9OX1BSSU5UQUJMRSAgICAgICAgID0gL1tceDAwLVx4MDhceDBCXHgwQ1x4MEUtXHgxRlx4N0YtXHg4NFx4ODYtXHg5Rlx1RkZGRVx1RkZGRl18W1x1RDgwMC1cdURCRkZdKD8hW1x1REMwMC1cdURGRkZdKXwoPzpbXlx1RDgwMC1cdURCRkZdfF4pW1x1REMwMC1cdURGRkZdLzsKdmFyIFBBVFRFUk5fTk9OX0FTQ0lJX0xJTkVfQlJFQUtTID0gL1tceDg1XHUyMDI4XHUyMDI5XS87CnZhciBQQVRURVJOX0ZMT1dfSU5ESUNBVE9SUyAgICAgICA9IC9bLFxbXF1ce1x9XS87CnZhciBQQVRURVJOX1RBR19IQU5ETEUgICAgICAgICAgICA9IC9eKD86IXwhIXwhW2EtelwtXSshKSQvaTsKdmFyIFBBVFRFUk5fVEFHX1VSSSAgICAgICAgICAgICAgID0gL14oPzohfFteLFxbXF1ce1x9XSkoPzolWzAtOWEtZl17Mn18WzAtOWEtelwtIztcL1w/OkAmPVwrXCQsX1wuIX5cKidcKFwpXFtcXV0pKiQvaTsKCgpmdW5jdGlvbiBpc19FT0woYykgewogIHJldHVybiAoYyA9PT0gMHgwQS8qIExGICovKSB8fCAoYyA9PT0gMHgwRC8qIENSICovKTsKfQoKZnVuY3Rpb24gaXNfV0hJVEVfU1BBQ0UoYykgewogIHJldHVybiAoYyA9PT0gMHgwOS8qIFRhYiAqLykgfHwgKGMgPT09IDB4MjAvKiBTcGFjZSAqLyk7Cn0KCmZ1bmN0aW9uIGlzX1dTX09SX0VPTChjKSB7CiAgcmV0dXJuIChjID09PSAweDA5LyogVGFiICovKSB8fAogICAgICAgICAoYyA9PT0gMHgyMC8qIFNwYWNlICovKSB8fAogICAgICAgICAoYyA9PT0gMHgwQS8qIExGICovKSB8fAogICAgICAgICAoYyA9PT0gMHgwRC8qIENSICovKTsKfQoKZnVuY3Rpb24gaXNfRkxPV19JTkRJQ0FUT1IoYykgewogIHJldHVybiBjID09PSAweDJDLyogLCAqLyB8fAogICAgICAgICBjID09PSAweDVCLyogWyAqLyB8fAogICAgICAgICBjID09PSAweDVELyogXSAqLyB8fAogICAgICAgICBjID09PSAweDdCLyogeyAqLyB8fAogICAgICAgICBjID09PSAweDdELyogfSAqLzsKfQoKZnVuY3Rpb24gZnJvbUhleENvZGUoYykgewogIHZhciBsYzsKCiAgaWYgKChjLyogMCAqLyA+PSAweDMwKSAmJiAoYyA8PSAweDM5LyogOSAqLykpIHsKICAgIHJldHVybiBjIC0gMHgzMDsKICB9CiAgbGMgPSBjIHwgMHgyMDsKCiAgaWYgKChsYy8qIGEgKi8gPj0gMHg2MSkgJiYgKGxjIDw9IDB4NjYvKiBmICovKSkgewogICAgcmV0dXJuIGxjIC0gMHg2MSArIDEwOwogIH0KCiAgcmV0dXJuIC0xOwp9CgpmdW5jdGlvbiBlc2NhcGVkSGV4TGVuKGMpIHsKICBpZiAoYyA9PT0gMHg3OC8qIHggKi8pIHsgcmV0dXJuIDI7IH0KICBpZiAoYyA9PT0gMHg3NS8qIHUgKi8pIHsgcmV0dXJuIDQ7IH0KICBpZiAoYyA9PT0gMHg1NS8qIFUgKi8pIHsgcmV0dXJuIDg7IH0KICByZXR1cm4gMDsKfQoKZnVuY3Rpb24gZnJvbURlY2ltYWxDb2RlKGMpIHsKICBpZiAoKGMvKiAwICovID49IDB4MzApICYmIChjIDw9IDB4MzkvKiA5ICovKSkgewogICAgcmV0dXJuIGMgLSAweDMwOwogIH0KCiAgcmV0dXJuIC0xOwp9CgpmdW5jdGlvbiBzaW1wbGVFc2NhcGVTZXF1ZW5jZShjKSB7CiAgcmV0dXJuIChjID09PSAweDMwLyogMCAqLykgPyAnXHgwMCcgOgogICAgICAgIChjID09PSAweDYxLyogYSAqLykgPyAnXHgwNycgOgogICAgICAgIChjID09PSAweDYyLyogYiAqLykgPyAnXHgwOCcgOgogICAgICAgIChjID09PSAweDc0LyogdCAqLykgPyAnXHgwOScgOgogICAgICAgIChjID09PSAweDA5LyogVGFiICovKSA/ICdceDA5JyA6CiAgICAgICAgKGMgPT09IDB4NkUvKiBuICovKSA/ICdceDBBJyA6CiAgICAgICAgKGMgPT09IDB4NzYvKiB2ICovKSA/ICdceDBCJyA6CiAgICAgICAgKGMgPT09IDB4NjYvKiBmICovKSA/ICdceDBDJyA6CiAgICAgICAgKGMgPT09IDB4NzIvKiByICovKSA/ICdceDBEJyA6CiAgICAgICAgKGMgPT09IDB4NjUvKiBlICovKSA/ICdceDFCJyA6CiAgICAgICAgKGMgPT09IDB4MjAvKiBTcGFjZSAqLykgPyAnICcgOgogICAgICAgIChjID09PSAweDIyLyogIiAqLykgPyAnXHgyMicgOgogICAgICAgIChjID09PSAweDJGLyogLyAqLykgPyAnLycgOgogICAgICAgIChjID09PSAweDVDLyogXCAqLykgPyAnXHg1QycgOgogICAgICAgIChjID09PSAweDRFLyogTiAqLykgPyAnXHg4NScgOgogICAgICAgIChjID09PSAweDVGLyogXyAqLykgPyAnXHhBMCcgOgogICAgICAgIChjID09PSAweDRDLyogTCAqLykgPyAnXHUyMDI4JyA6CiAgICAgICAgKGMgPT09IDB4NTAvKiBQICovKSA/ICdcdTIwMjknIDogJyc7Cn0KCmZ1bmN0aW9uIGNoYXJGcm9tQ29kZXBvaW50KGMpIHsKICBpZiAoYyA8PSAweEZGRkYpIHsKICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKGMpOwogIH0KICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZSgKICAgICgoYyAtIDB4MDEwMDAwKSA+PiAxMCkgKyAweEQ4MDAsCiAgICAoKGMgLSAweDAxMDAwMCkgJiAweDAzRkYpICsgMHhEQzAwCiAgKTsKfQoKdmFyIHNpbXBsZUVzY2FwZUNoZWNrID0gbmV3IEFycmF5KDI1Nik7IC8vIGludGVnZXIsIGZvciBmYXN0IGFjY2Vzcwp2YXIgc2ltcGxlRXNjYXBlTWFwID0gbmV3IEFycmF5KDI1Nik7CmZvciAodmFyIGkgPSAwOyBpIDwgMjU2OyBpKyspIHsKICBzaW1wbGVFc2NhcGVDaGVja1tpXSA9IHNpbXBsZUVzY2FwZVNlcXVlbmNlKGkpID8gMSA6IDA7CiAgc2ltcGxlRXNjYXBlTWFwW2ldID0gc2ltcGxlRXNjYXBlU2VxdWVuY2UoaSk7Cn0KCgpmdW5jdGlvbiBTdGF0ZShpbnB1dCwgb3B0aW9ucykgewogIHRoaXMuaW5wdXQgPSBpbnB1dDsKCiAgdGhpcy5maWxlbmFtZSAgPSBvcHRpb25zWydmaWxlbmFtZSddICB8fCBudWxsOwogIHRoaXMuc2NoZW1hICAgID0gb3B0aW9uc1snc2NoZW1hJ10gICAgfHwgREVGQVVMVF9GVUxMX1NDSEVNQTsKICB0aGlzLm9uV2FybmluZyA9IG9wdGlvbnNbJ29uV2FybmluZyddIHx8IG51bGw7CiAgdGhpcy5sZWdhY3kgICAgPSBvcHRpb25zWydsZWdhY3knXSAgICB8fCBmYWxzZTsKICB0aGlzLmpzb24gICAgICA9IG9wdGlvbnNbJ2pzb24nXSAgICAgIHx8IGZhbHNlOwogIHRoaXMubGlzdGVuZXIgID0gb3B0aW9uc1snbGlzdGVuZXInXSAgfHwgbnVsbDsKCiAgdGhpcy5pbXBsaWNpdFR5cGVzID0gdGhpcy5zY2hlbWEuY29tcGlsZWRJbXBsaWNpdDsKICB0aGlzLnR5cGVNYXAgICAgICAgPSB0aGlzLnNjaGVtYS5jb21waWxlZFR5cGVNYXA7CgogIHRoaXMubGVuZ3RoICAgICA9IGlucHV0Lmxlbmd0aDsKICB0aGlzLnBvc2l0aW9uICAgPSAwOwogIHRoaXMubGluZSAgICAgICA9IDA7CiAgdGhpcy5saW5lU3RhcnQgID0gMDsKICB0aGlzLmxpbmVJbmRlbnQgPSAwOwoKICB0aGlzLmRvY3VtZW50cyA9IFtdOwoKfQoKCmZ1bmN0aW9uIGdlbmVyYXRlRXJyb3Ioc3RhdGUsIG1lc3NhZ2UpIHsKICByZXR1cm4gbmV3IFlBTUxFeGNlcHRpb24oCiAgICBtZXNzYWdlLAogICAgbmV3IE1hcmsoc3RhdGUuZmlsZW5hbWUsIHN0YXRlLmlucHV0LCBzdGF0ZS5wb3NpdGlvbiwgc3RhdGUubGluZSwgKHN0YXRlLnBvc2l0aW9uIC0gc3RhdGUubGluZVN0YXJ0KSkpOwp9CgpmdW5jdGlvbiB0aHJvd0Vycm9yKHN0YXRlLCBtZXNzYWdlKSB7CiAgdGhyb3cgZ2VuZXJhdGVFcnJvcihzdGF0ZSwgbWVzc2FnZSk7Cn0KCmZ1bmN0aW9uIHRocm93V2FybmluZyhzdGF0ZSwgbWVzc2FnZSkgewogIGlmIChzdGF0ZS5vbldhcm5pbmcpIHsKICAgIHN0YXRlLm9uV2FybmluZy5jYWxsKG51bGwsIGdlbmVyYXRlRXJyb3Ioc3RhdGUsIG1lc3NhZ2UpKTsKICB9Cn0KCgp2YXIgZGlyZWN0aXZlSGFuZGxlcnMgPSB7CgogIFlBTUw6IGZ1bmN0aW9uIGhhbmRsZVlhbWxEaXJlY3RpdmUoc3RhdGUsIG5hbWUsIGFyZ3MpIHsKCiAgICB2YXIgbWF0Y2gsIG1ham9yLCBtaW5vcjsKCiAgICBpZiAoc3RhdGUudmVyc2lvbiAhPT0gbnVsbCkgewogICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZHVwbGljYXRpb24gb2YgJVlBTUwgZGlyZWN0aXZlJyk7CiAgICB9CgogICAgaWYgKGFyZ3MubGVuZ3RoICE9PSAxKSB7CiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdZQU1MIGRpcmVjdGl2ZSBhY2NlcHRzIGV4YWN0bHkgb25lIGFyZ3VtZW50Jyk7CiAgICB9CgogICAgbWF0Y2ggPSAvXihbMC05XSspXC4oWzAtOV0rKSQvLmV4ZWMoYXJnc1swXSk7CgogICAgaWYgKG1hdGNoID09PSBudWxsKSB7CiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdpbGwtZm9ybWVkIGFyZ3VtZW50IG9mIHRoZSBZQU1MIGRpcmVjdGl2ZScpOwogICAgfQoKICAgIG1ham9yID0gcGFyc2VJbnQobWF0Y2hbMV0sIDEwKTsKICAgIG1pbm9yID0gcGFyc2VJbnQobWF0Y2hbMl0sIDEwKTsKCiAgICBpZiAobWFqb3IgIT09IDEpIHsKICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3VuYWNjZXB0YWJsZSBZQU1MIHZlcnNpb24gb2YgdGhlIGRvY3VtZW50Jyk7CiAgICB9CgogICAgc3RhdGUudmVyc2lvbiA9IGFyZ3NbMF07CiAgICBzdGF0ZS5jaGVja0xpbmVCcmVha3MgPSAobWlub3IgPCAyKTsKCiAgICBpZiAobWlub3IgIT09IDEgJiYgbWlub3IgIT09IDIpIHsKICAgICAgdGhyb3dXYXJuaW5nKHN0YXRlLCAndW5zdXBwb3J0ZWQgWUFNTCB2ZXJzaW9uIG9mIHRoZSBkb2N1bWVudCcpOwogICAgfQogIH0sCgogIFRBRzogZnVuY3Rpb24gaGFuZGxlVGFnRGlyZWN0aXZlKHN0YXRlLCBuYW1lLCBhcmdzKSB7CgogICAgdmFyIGhhbmRsZSwgcHJlZml4OwoKICAgIGlmIChhcmdzLmxlbmd0aCAhPT0gMikgewogICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnVEFHIGRpcmVjdGl2ZSBhY2NlcHRzIGV4YWN0bHkgdHdvIGFyZ3VtZW50cycpOwogICAgfQoKICAgIGhhbmRsZSA9IGFyZ3NbMF07CiAgICBwcmVmaXggPSBhcmdzWzFdOwoKICAgIGlmICghUEFUVEVSTl9UQUdfSEFORExFLnRlc3QoaGFuZGxlKSkgewogICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnaWxsLWZvcm1lZCB0YWcgaGFuZGxlIChmaXJzdCBhcmd1bWVudCkgb2YgdGhlIFRBRyBkaXJlY3RpdmUnKTsKICAgIH0KCiAgICBpZiAoX2hhc093blByb3BlcnR5LmNhbGwoc3RhdGUudGFnTWFwLCBoYW5kbGUpKSB7CiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd0aGVyZSBpcyBhIHByZXZpb3VzbHkgZGVjbGFyZWQgc3VmZml4IGZvciAiJyArIGhhbmRsZSArICciIHRhZyBoYW5kbGUnKTsKICAgIH0KCiAgICBpZiAoIVBBVFRFUk5fVEFHX1VSSS50ZXN0KHByZWZpeCkpIHsKICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2lsbC1mb3JtZWQgdGFnIHByZWZpeCAoc2Vjb25kIGFyZ3VtZW50KSBvZiB0aGUgVEFHIGRpcmVjdGl2ZScpOwogICAgfQoKICAgIHN0YXRlLnRhZ01hcFtoYW5kbGVdID0gcHJlZml4OwogIH0KfTsKCgpmdW5jdGlvbiBjYXB0dXJlU2VnbWVudChzdGF0ZSwgc3RhcnQsIGVuZCwgY2hlY2tKc29uKSB7CiAgdmFyIF9wb3NpdGlvbiwgX2xlbmd0aCwgX2NoYXJhY3RlciwgX3Jlc3VsdDsKCiAgaWYgKHN0YXJ0IDwgZW5kKSB7CiAgICBfcmVzdWx0ID0gc3RhdGUuaW5wdXQuc2xpY2Uoc3RhcnQsIGVuZCk7CgogICAgaWYgKGNoZWNrSnNvbikgewogICAgICBmb3IgKF9wb3NpdGlvbiA9IDAsIF9sZW5ndGggPSBfcmVzdWx0Lmxlbmd0aDsgX3Bvc2l0aW9uIDwgX2xlbmd0aDsgX3Bvc2l0aW9uICs9IDEpIHsKICAgICAgICBfY2hhcmFjdGVyID0gX3Jlc3VsdC5jaGFyQ29kZUF0KF9wb3NpdGlvbik7CiAgICAgICAgaWYgKCEoX2NoYXJhY3RlciA9PT0gMHgwOSB8fAogICAgICAgICAgICAgIChfY2hhcmFjdGVyID49IDB4MjAgJiYgX2NoYXJhY3RlciA8PSAweDEwRkZGRikpKSB7CiAgICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZXhwZWN0ZWQgdmFsaWQgSlNPTiBjaGFyYWN0ZXInKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0gZWxzZSBpZiAoUEFUVEVSTl9OT05fUFJJTlRBQkxFLnRlc3QoX3Jlc3VsdCkpIHsKICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3RoZSBzdHJlYW0gY29udGFpbnMgbm9uLXByaW50YWJsZSBjaGFyYWN0ZXJzJyk7CiAgICB9CgogICAgc3RhdGUucmVzdWx0ICs9IF9yZXN1bHQ7CiAgfQp9CgpmdW5jdGlvbiBtZXJnZU1hcHBpbmdzKHN0YXRlLCBkZXN0aW5hdGlvbiwgc291cmNlLCBvdmVycmlkYWJsZUtleXMpIHsKICB2YXIgc291cmNlS2V5cywga2V5LCBpbmRleCwgcXVhbnRpdHk7CgogIGlmICghY29tbW9uLmlzT2JqZWN0KHNvdXJjZSkpIHsKICAgIHRocm93RXJyb3Ioc3RhdGUsICdjYW5ub3QgbWVyZ2UgbWFwcGluZ3M7IHRoZSBwcm92aWRlZCBzb3VyY2Ugb2JqZWN0IGlzIHVuYWNjZXB0YWJsZScpOwogIH0KCiAgc291cmNlS2V5cyA9IE9iamVjdC5rZXlzKHNvdXJjZSk7CgogIGZvciAoaW5kZXggPSAwLCBxdWFudGl0eSA9IHNvdXJjZUtleXMubGVuZ3RoOyBpbmRleCA8IHF1YW50aXR5OyBpbmRleCArPSAxKSB7CiAgICBrZXkgPSBzb3VyY2VLZXlzW2luZGV4XTsKCiAgICBpZiAoIV9oYXNPd25Qcm9wZXJ0eS5jYWxsKGRlc3RpbmF0aW9uLCBrZXkpKSB7CiAgICAgIGRlc3RpbmF0aW9uW2tleV0gPSBzb3VyY2Vba2V5XTsKICAgICAgb3ZlcnJpZGFibGVLZXlzW2tleV0gPSB0cnVlOwogICAgfQogIH0KfQoKZnVuY3Rpb24gc3RvcmVNYXBwaW5nUGFpcihzdGF0ZSwgX3Jlc3VsdCwgb3ZlcnJpZGFibGVLZXlzLCBrZXlUYWcsIGtleU5vZGUsIHZhbHVlTm9kZSwgc3RhcnRMaW5lLCBzdGFydFBvcykgewogIHZhciBpbmRleCwgcXVhbnRpdHk7CgogIGtleU5vZGUgPSBTdHJpbmcoa2V5Tm9kZSk7CgogIGlmIChfcmVzdWx0ID09PSBudWxsKSB7CiAgICBfcmVzdWx0ID0ge307CiAgfQoKICBpZiAoa2V5VGFnID09PSAndGFnOnlhbWwub3JnLDIwMDI6bWVyZ2UnKSB7CiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZU5vZGUpKSB7CiAgICAgIGZvciAoaW5kZXggPSAwLCBxdWFudGl0eSA9IHZhbHVlTm9kZS5sZW5ndGg7IGluZGV4IDwgcXVhbnRpdHk7IGluZGV4ICs9IDEpIHsKICAgICAgICBtZXJnZU1hcHBpbmdzKHN0YXRlLCBfcmVzdWx0LCB2YWx1ZU5vZGVbaW5kZXhdLCBvdmVycmlkYWJsZUtleXMpOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBtZXJnZU1hcHBpbmdzKHN0YXRlLCBfcmVzdWx0LCB2YWx1ZU5vZGUsIG92ZXJyaWRhYmxlS2V5cyk7CiAgICB9CiAgfSBlbHNlIHsKICAgIGlmICghc3RhdGUuanNvbiAmJgogICAgICAgICFfaGFzT3duUHJvcGVydHkuY2FsbChvdmVycmlkYWJsZUtleXMsIGtleU5vZGUpICYmCiAgICAgICAgX2hhc093blByb3BlcnR5LmNhbGwoX3Jlc3VsdCwga2V5Tm9kZSkpIHsKICAgICAgc3RhdGUubGluZSA9IHN0YXJ0TGluZSB8fCBzdGF0ZS5saW5lOwogICAgICBzdGF0ZS5wb3NpdGlvbiA9IHN0YXJ0UG9zIHx8IHN0YXRlLnBvc2l0aW9uOwogICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZHVwbGljYXRlZCBtYXBwaW5nIGtleScpOwogICAgfQogICAgX3Jlc3VsdFtrZXlOb2RlXSA9IHZhbHVlTm9kZTsKICAgIGRlbGV0ZSBvdmVycmlkYWJsZUtleXNba2V5Tm9kZV07CiAgfQoKICByZXR1cm4gX3Jlc3VsdDsKfQoKZnVuY3Rpb24gcmVhZExpbmVCcmVhayhzdGF0ZSkgewogIHZhciBjaDsKCiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTsKCiAgaWYgKGNoID09PSAweDBBLyogTEYgKi8pIHsKICAgIHN0YXRlLnBvc2l0aW9uKys7CiAgfSBlbHNlIGlmIChjaCA9PT0gMHgwRC8qIENSICovKSB7CiAgICBzdGF0ZS5wb3NpdGlvbisrOwogICAgaWYgKHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pID09PSAweDBBLyogTEYgKi8pIHsKICAgICAgc3RhdGUucG9zaXRpb24rKzsKICAgIH0KICB9IGVsc2UgewogICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2EgbGluZSBicmVhayBpcyBleHBlY3RlZCcpOwogIH0KCiAgc3RhdGUubGluZSArPSAxOwogIHN0YXRlLmxpbmVTdGFydCA9IHN0YXRlLnBvc2l0aW9uOwp9CgpmdW5jdGlvbiBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCBhbGxvd0NvbW1lbnRzLCBjaGVja0luZGVudCkgewogIHZhciBsaW5lQnJlYWtzID0gMCwKICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTsKCiAgd2hpbGUgKGNoICE9PSAwKSB7CiAgICB3aGlsZSAoaXNfV0hJVEVfU1BBQ0UoY2gpKSB7CiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTsKICAgIH0KCiAgICBpZiAoYWxsb3dDb21tZW50cyAmJiBjaCA9PT0gMHgyMy8qICMgKi8pIHsKICAgICAgZG8gewogICAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTsKICAgICAgfSB3aGlsZSAoY2ggIT09IDB4MEEvKiBMRiAqLyAmJiBjaCAhPT0gMHgwRC8qIENSICovICYmIGNoICE9PSAwKTsKICAgIH0KCiAgICBpZiAoaXNfRU9MKGNoKSkgewogICAgICByZWFkTGluZUJyZWFrKHN0YXRlKTsKCiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7CiAgICAgIGxpbmVCcmVha3MrKzsKICAgICAgc3RhdGUubGluZUluZGVudCA9IDA7CgogICAgICB3aGlsZSAoY2ggPT09IDB4MjAvKiBTcGFjZSAqLykgewogICAgICAgIHN0YXRlLmxpbmVJbmRlbnQrKzsKICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIGJyZWFrOwogICAgfQogIH0KCiAgaWYgKGNoZWNrSW5kZW50ICE9PSAtMSAmJiBsaW5lQnJlYWtzICE9PSAwICYmIHN0YXRlLmxpbmVJbmRlbnQgPCBjaGVja0luZGVudCkgewogICAgdGhyb3dXYXJuaW5nKHN0YXRlLCAnZGVmaWNpZW50IGluZGVudGF0aW9uJyk7CiAgfQoKICByZXR1cm4gbGluZUJyZWFrczsKfQoKZnVuY3Rpb24gdGVzdERvY3VtZW50U2VwYXJhdG9yKHN0YXRlKSB7CiAgdmFyIF9wb3NpdGlvbiA9IHN0YXRlLnBvc2l0aW9uLAogICAgICBjaDsKCiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KF9wb3NpdGlvbik7CiAgaWYgKChjaCA9PT0gMHgyRC8qIC0gKi8gfHwgY2ggPT09IDB4MkUvKiAuICovKSAmJgogICAgICBjaCA9PT0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChfcG9zaXRpb24gKyAxKSAmJgogICAgICBjaCA9PT0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChfcG9zaXRpb24gKyAyKSkgewoKICAgIF9wb3NpdGlvbiArPSAzOwoKICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChfcG9zaXRpb24pOwoKICAgIGlmIChjaCA9PT0gMCB8fCBpc19XU19PUl9FT0woY2gpKSB7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQogIH0KCiAgcmV0dXJuIGZhbHNlOwp9CgpmdW5jdGlvbiB3cml0ZUZvbGRlZExpbmVzKHN0YXRlLCBjb3VudCkgewogIGlmIChjb3VudCA9PT0gMSkgewogICAgc3RhdGUucmVzdWx0ICs9ICcgJzsKICB9IGVsc2UgaWYgKGNvdW50ID4gMSkgewogICAgc3RhdGUucmVzdWx0ICs9IGNvbW1vbi5yZXBlYXQoJ1xuJywgY291bnQgLSAxKTsKICB9Cn0KCgpmdW5jdGlvbiByZWFkUGxhaW5TY2FsYXIoc3RhdGUsIG5vZGVJbmRlbnQsIHdpdGhpbkZsb3dDb2xsZWN0aW9uKSB7CiAgdmFyIHByZWNlZGluZywKICAgICAgZm9sbG93aW5nLAogICAgICBjYXB0dXJlU3RhcnQsCiAgICAgIGNhcHR1cmVFbmQsCiAgICAgIGhhc1BlbmRpbmdDb250ZW50LAogICAgICBfbGluZSwKICAgICAgX2xpbmVTdGFydCwKICAgICAgX2xpbmVJbmRlbnQsCiAgICAgIF9raW5kID0gc3RhdGUua2luZCwKICAgICAgX3Jlc3VsdCA9IHN0YXRlLnJlc3VsdCwKICAgICAgY2g7CgogIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7CgogIGlmIChpc19XU19PUl9FT0woY2gpICAgICAgfHwKICAgICAgaXNfRkxPV19JTkRJQ0FUT1IoY2gpIHx8CiAgICAgIGNoID09PSAweDIzLyogIyAqLyAgICB8fAogICAgICBjaCA9PT0gMHgyNi8qICYgKi8gICAgfHwKICAgICAgY2ggPT09IDB4MkEvKiAqICovICAgIHx8CiAgICAgIGNoID09PSAweDIxLyogISAqLyAgICB8fAogICAgICBjaCA9PT0gMHg3Qy8qIHwgKi8gICAgfHwKICAgICAgY2ggPT09IDB4M0UvKiA+ICovICAgIHx8CiAgICAgIGNoID09PSAweDI3LyogJyAqLyAgICB8fAogICAgICBjaCA9PT0gMHgyMi8qICIgKi8gICAgfHwKICAgICAgY2ggPT09IDB4MjUvKiAlICovICAgIHx8CiAgICAgIGNoID09PSAweDQwLyogQCAqLyAgICB8fAogICAgICBjaCA9PT0gMHg2MC8qIGAgKi8pIHsKICAgIHJldHVybiBmYWxzZTsKICB9CgogIGlmIChjaCA9PT0gMHgzRi8qID8gKi8gfHwgY2ggPT09IDB4MkQvKiAtICovKSB7CiAgICBmb2xsb3dpbmcgPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uICsgMSk7CgogICAgaWYgKGlzX1dTX09SX0VPTChmb2xsb3dpbmcpIHx8CiAgICAgICAgd2l0aGluRmxvd0NvbGxlY3Rpb24gJiYgaXNfRkxPV19JTkRJQ0FUT1IoZm9sbG93aW5nKSkgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgfQoKICBzdGF0ZS5raW5kID0gJ3NjYWxhcic7CiAgc3RhdGUucmVzdWx0ID0gJyc7CiAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uOwogIGhhc1BlbmRpbmdDb250ZW50ID0gZmFsc2U7CgogIHdoaWxlIChjaCAhPT0gMCkgewogICAgaWYgKGNoID09PSAweDNBLyogOiAqLykgewogICAgICBmb2xsb3dpbmcgPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uICsgMSk7CgogICAgICBpZiAoaXNfV1NfT1JfRU9MKGZvbGxvd2luZykgfHwKICAgICAgICAgIHdpdGhpbkZsb3dDb2xsZWN0aW9uICYmIGlzX0ZMT1dfSU5ESUNBVE9SKGZvbGxvd2luZykpIHsKICAgICAgICBicmVhazsKICAgICAgfQoKICAgIH0gZWxzZSBpZiAoY2ggPT09IDB4MjMvKiAjICovKSB7CiAgICAgIHByZWNlZGluZyA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24gLSAxKTsKCiAgICAgIGlmIChpc19XU19PUl9FT0wocHJlY2VkaW5nKSkgewogICAgICAgIGJyZWFrOwogICAgICB9CgogICAgfSBlbHNlIGlmICgoc3RhdGUucG9zaXRpb24gPT09IHN0YXRlLmxpbmVTdGFydCAmJiB0ZXN0RG9jdW1lbnRTZXBhcmF0b3Ioc3RhdGUpKSB8fAogICAgICAgICAgICAgICB3aXRoaW5GbG93Q29sbGVjdGlvbiAmJiBpc19GTE9XX0lORElDQVRPUihjaCkpIHsKICAgICAgYnJlYWs7CgogICAgfSBlbHNlIGlmIChpc19FT0woY2gpKSB7CiAgICAgIF9saW5lID0gc3RhdGUubGluZTsKICAgICAgX2xpbmVTdGFydCA9IHN0YXRlLmxpbmVTdGFydDsKICAgICAgX2xpbmVJbmRlbnQgPSBzdGF0ZS5saW5lSW5kZW50OwogICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCBmYWxzZSwgLTEpOwoKICAgICAgaWYgKHN0YXRlLmxpbmVJbmRlbnQgPj0gbm9kZUluZGVudCkgewogICAgICAgIGhhc1BlbmRpbmdDb250ZW50ID0gdHJ1ZTsKICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pOwogICAgICAgIGNvbnRpbnVlOwogICAgICB9IGVsc2UgewogICAgICAgIHN0YXRlLnBvc2l0aW9uID0gY2FwdHVyZUVuZDsKICAgICAgICBzdGF0ZS5saW5lID0gX2xpbmU7CiAgICAgICAgc3RhdGUubGluZVN0YXJ0ID0gX2xpbmVTdGFydDsKICAgICAgICBzdGF0ZS5saW5lSW5kZW50ID0gX2xpbmVJbmRlbnQ7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KCiAgICBpZiAoaGFzUGVuZGluZ0NvbnRlbnQpIHsKICAgICAgY2FwdHVyZVNlZ21lbnQoc3RhdGUsIGNhcHR1cmVTdGFydCwgY2FwdHVyZUVuZCwgZmFsc2UpOwogICAgICB3cml0ZUZvbGRlZExpbmVzKHN0YXRlLCBzdGF0ZS5saW5lIC0gX2xpbmUpOwogICAgICBjYXB0dXJlU3RhcnQgPSBjYXB0dXJlRW5kID0gc3RhdGUucG9zaXRpb247CiAgICAgIGhhc1BlbmRpbmdDb250ZW50ID0gZmFsc2U7CiAgICB9CgogICAgaWYgKCFpc19XSElURV9TUEFDRShjaCkpIHsKICAgICAgY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uICsgMTsKICAgIH0KCiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7CiAgfQoKICBjYXB0dXJlU2VnbWVudChzdGF0ZSwgY2FwdHVyZVN0YXJ0LCBjYXB0dXJlRW5kLCBmYWxzZSk7CgogIGlmIChzdGF0ZS5yZXN1bHQpIHsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgc3RhdGUua2luZCA9IF9raW5kOwogIHN0YXRlLnJlc3VsdCA9IF9yZXN1bHQ7CiAgcmV0dXJuIGZhbHNlOwp9CgpmdW5jdGlvbiByZWFkU2luZ2xlUXVvdGVkU2NhbGFyKHN0YXRlLCBub2RlSW5kZW50KSB7CiAgdmFyIGNoLAogICAgICBjYXB0dXJlU3RhcnQsIGNhcHR1cmVFbmQ7CgogIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7CgogIGlmIChjaCAhPT0gMHgyNy8qICcgKi8pIHsKICAgIHJldHVybiBmYWxzZTsKICB9CgogIHN0YXRlLmtpbmQgPSAnc2NhbGFyJzsKICBzdGF0ZS5yZXN1bHQgPSAnJzsKICBzdGF0ZS5wb3NpdGlvbisrOwogIGNhcHR1cmVTdGFydCA9IGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjsKCiAgd2hpbGUgKChjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pKSAhPT0gMCkgewogICAgaWYgKGNoID09PSAweDI3LyogJyAqLykgewogICAgICBjYXB0dXJlU2VnbWVudChzdGF0ZSwgY2FwdHVyZVN0YXJ0LCBzdGF0ZS5wb3NpdGlvbiwgdHJ1ZSk7CiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTsKCiAgICAgIGlmIChjaCA9PT0gMHgyNy8qICcgKi8pIHsKICAgICAgICBjYXB0dXJlU3RhcnQgPSBzdGF0ZS5wb3NpdGlvbjsKICAgICAgICBzdGF0ZS5wb3NpdGlvbisrOwogICAgICAgIGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgIH0gZWxzZSBpZiAoaXNfRU9MKGNoKSkgewogICAgICBjYXB0dXJlU2VnbWVudChzdGF0ZSwgY2FwdHVyZVN0YXJ0LCBjYXB0dXJlRW5kLCB0cnVlKTsKICAgICAgd3JpdGVGb2xkZWRMaW5lcyhzdGF0ZSwgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgZmFsc2UsIG5vZGVJbmRlbnQpKTsKICAgICAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uOwoKICAgIH0gZWxzZSBpZiAoc3RhdGUucG9zaXRpb24gPT09IHN0YXRlLmxpbmVTdGFydCAmJiB0ZXN0RG9jdW1lbnRTZXBhcmF0b3Ioc3RhdGUpKSB7CiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmV4cGVjdGVkIGVuZCBvZiB0aGUgZG9jdW1lbnQgd2l0aGluIGEgc2luZ2xlIHF1b3RlZCBzY2FsYXInKTsKCiAgICB9IGVsc2UgewogICAgICBzdGF0ZS5wb3NpdGlvbisrOwogICAgICBjYXB0dXJlRW5kID0gc3RhdGUucG9zaXRpb247CiAgICB9CiAgfQoKICB0aHJvd0Vycm9yKHN0YXRlLCAndW5leHBlY3RlZCBlbmQgb2YgdGhlIHN0cmVhbSB3aXRoaW4gYSBzaW5nbGUgcXVvdGVkIHNjYWxhcicpOwp9CgpmdW5jdGlvbiByZWFkRG91YmxlUXVvdGVkU2NhbGFyKHN0YXRlLCBub2RlSW5kZW50KSB7CiAgdmFyIGNhcHR1cmVTdGFydCwKICAgICAgY2FwdHVyZUVuZCwKICAgICAgaGV4TGVuZ3RoLAogICAgICBoZXhSZXN1bHQsCiAgICAgIHRtcCwKICAgICAgY2g7CgogIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7CgogIGlmIChjaCAhPT0gMHgyMi8qICIgKi8pIHsKICAgIHJldHVybiBmYWxzZTsKICB9CgogIHN0YXRlLmtpbmQgPSAnc2NhbGFyJzsKICBzdGF0ZS5yZXN1bHQgPSAnJzsKICBzdGF0ZS5wb3NpdGlvbisrOwogIGNhcHR1cmVTdGFydCA9IGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjsKCiAgd2hpbGUgKChjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pKSAhPT0gMCkgewogICAgaWYgKGNoID09PSAweDIyLyogIiAqLykgewogICAgICBjYXB0dXJlU2VnbWVudChzdGF0ZSwgY2FwdHVyZVN0YXJ0LCBzdGF0ZS5wb3NpdGlvbiwgdHJ1ZSk7CiAgICAgIHN0YXRlLnBvc2l0aW9uKys7CiAgICAgIHJldHVybiB0cnVlOwoKICAgIH0gZWxzZSBpZiAoY2ggPT09IDB4NUMvKiBcICovKSB7CiAgICAgIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIHN0YXRlLnBvc2l0aW9uLCB0cnVlKTsKICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pOwoKICAgICAgaWYgKGlzX0VPTChjaCkpIHsKICAgICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCBmYWxzZSwgbm9kZUluZGVudCk7CiAgICAgIH0gZWxzZSBpZiAoY2ggPCAyNTYgJiYgc2ltcGxlRXNjYXBlQ2hlY2tbY2hdKSB7CiAgICAgICAgc3RhdGUucmVzdWx0ICs9IHNpbXBsZUVzY2FwZU1hcFtjaF07CiAgICAgICAgc3RhdGUucG9zaXRpb24rKzsKCiAgICAgIH0gZWxzZSBpZiAoKHRtcCA9IGVzY2FwZWRIZXhMZW4oY2gpKSA+IDApIHsKICAgICAgICBoZXhMZW5ndGggPSB0bXA7CiAgICAgICAgaGV4UmVzdWx0ID0gMDsKCiAgICAgICAgZm9yICg7IGhleExlbmd0aCA+IDA7IGhleExlbmd0aC0tKSB7CiAgICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7CgogICAgICAgICAgaWYgKCh0bXAgPSBmcm9tSGV4Q29kZShjaCkpID49IDApIHsKICAgICAgICAgICAgaGV4UmVzdWx0ID0gKGhleFJlc3VsdCA8PCA0KSArIHRtcDsKCiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZXhwZWN0ZWQgaGV4YWRlY2ltYWwgY2hhcmFjdGVyJyk7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBzdGF0ZS5yZXN1bHQgKz0gY2hhckZyb21Db2RlcG9pbnQoaGV4UmVzdWx0KTsKCiAgICAgICAgc3RhdGUucG9zaXRpb24rKzsKCiAgICAgIH0gZWxzZSB7CiAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3Vua25vd24gZXNjYXBlIHNlcXVlbmNlJyk7CiAgICAgIH0KCiAgICAgIGNhcHR1cmVTdGFydCA9IGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjsKCiAgICB9IGVsc2UgaWYgKGlzX0VPTChjaCkpIHsKICAgICAgY2FwdHVyZVNlZ21lbnQoc3RhdGUsIGNhcHR1cmVTdGFydCwgY2FwdHVyZUVuZCwgdHJ1ZSk7CiAgICAgIHdyaXRlRm9sZGVkTGluZXMoc3RhdGUsIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIGZhbHNlLCBub2RlSW5kZW50KSk7CiAgICAgIGNhcHR1cmVTdGFydCA9IGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjsKCiAgICB9IGVsc2UgaWYgKHN0YXRlLnBvc2l0aW9uID09PSBzdGF0ZS5saW5lU3RhcnQgJiYgdGVzdERvY3VtZW50U2VwYXJhdG9yKHN0YXRlKSkgewogICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndW5leHBlY3RlZCBlbmQgb2YgdGhlIGRvY3VtZW50IHdpdGhpbiBhIGRvdWJsZSBxdW90ZWQgc2NhbGFyJyk7CgogICAgfSBlbHNlIHsKICAgICAgc3RhdGUucG9zaXRpb24rKzsKICAgICAgY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uOwogICAgfQogIH0KCiAgdGhyb3dFcnJvcihzdGF0ZSwgJ3VuZXhwZWN0ZWQgZW5kIG9mIHRoZSBzdHJlYW0gd2l0aGluIGEgZG91YmxlIHF1b3RlZCBzY2FsYXInKTsKfQoKZnVuY3Rpb24gcmVhZEZsb3dDb2xsZWN0aW9uKHN0YXRlLCBub2RlSW5kZW50KSB7CiAgdmFyIHJlYWROZXh0ID0gdHJ1ZSwKICAgICAgX2xpbmUsCiAgICAgIF90YWcgICAgID0gc3RhdGUudGFnLAogICAgICBfcmVzdWx0LAogICAgICBfYW5jaG9yICA9IHN0YXRlLmFuY2hvciwKICAgICAgZm9sbG93aW5nLAogICAgICB0ZXJtaW5hdG9yLAogICAgICBpc1BhaXIsCiAgICAgIGlzRXhwbGljaXRQYWlyLAogICAgICBpc01hcHBpbmcsCiAgICAgIG92ZXJyaWRhYmxlS2V5cyA9IHt9LAogICAgICBrZXlOb2RlLAogICAgICBrZXlUYWcsCiAgICAgIHZhbHVlTm9kZSwKICAgICAgY2g7CgogIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7CgogIGlmIChjaCA9PT0gMHg1Qi8qIFsgKi8pIHsKICAgIHRlcm1pbmF0b3IgPSAweDVEOwogICAgaXNNYXBwaW5nID0gZmFsc2U7CiAgICBfcmVzdWx0ID0gW107CiAgfSBlbHNlIGlmIChjaCA9PT0gMHg3Qi8qIHsgKi8pIHsKICAgIHRlcm1pbmF0b3IgPSAweDdEOwogICAgaXNNYXBwaW5nID0gdHJ1ZTsKICAgIF9yZXN1bHQgPSB7fTsKICB9IGVsc2UgewogICAgcmV0dXJuIGZhbHNlOwogIH0KCiAgaWYgKHN0YXRlLmFuY2hvciAhPT0gbnVsbCkgewogICAgc3RhdGUuYW5jaG9yTWFwW3N0YXRlLmFuY2hvcl0gPSBfcmVzdWx0OwogIH0KCiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pOwoKICB3aGlsZSAoY2ggIT09IDApIHsKICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIG5vZGVJbmRlbnQpOwoKICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7CgogICAgaWYgKGNoID09PSB0ZXJtaW5hdG9yKSB7CiAgICAgIHN0YXRlLnBvc2l0aW9uKys7CiAgICAgIHN0YXRlLnRhZyA9IF90YWc7CiAgICAgIHN0YXRlLmFuY2hvciA9IF9hbmNob3I7CiAgICAgIHN0YXRlLmtpbmQgPSBpc01hcHBpbmcgPyAnbWFwcGluZycgOiAnc2VxdWVuY2UnOwogICAgICBzdGF0ZS5yZXN1bHQgPSBfcmVzdWx0OwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0gZWxzZSBpZiAoIXJlYWROZXh0KSB7CiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdtaXNzZWQgY29tbWEgYmV0d2VlbiBmbG93IGNvbGxlY3Rpb24gZW50cmllcycpOwogICAgfQoKICAgIGtleVRhZyA9IGtleU5vZGUgPSB2YWx1ZU5vZGUgPSBudWxsOwogICAgaXNQYWlyID0gaXNFeHBsaWNpdFBhaXIgPSBmYWxzZTsKCiAgICBpZiAoY2ggPT09IDB4M0YvKiA/ICovKSB7CiAgICAgIGZvbGxvd2luZyA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24gKyAxKTsKCiAgICAgIGlmIChpc19XU19PUl9FT0woZm9sbG93aW5nKSkgewogICAgICAgIGlzUGFpciA9IGlzRXhwbGljaXRQYWlyID0gdHJ1ZTsKICAgICAgICBzdGF0ZS5wb3NpdGlvbisrOwogICAgICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIG5vZGVJbmRlbnQpOwogICAgICB9CiAgICB9CgogICAgX2xpbmUgPSBzdGF0ZS5saW5lOwogICAgY29tcG9zZU5vZGUoc3RhdGUsIG5vZGVJbmRlbnQsIENPTlRFWFRfRkxPV19JTiwgZmFsc2UsIHRydWUpOwogICAga2V5VGFnID0gc3RhdGUudGFnOwogICAga2V5Tm9kZSA9IHN0YXRlLnJlc3VsdDsKICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIG5vZGVJbmRlbnQpOwoKICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7CgogICAgaWYgKChpc0V4cGxpY2l0UGFpciB8fCBzdGF0ZS5saW5lID09PSBfbGluZSkgJiYgY2ggPT09IDB4M0EvKiA6ICovKSB7CiAgICAgIGlzUGFpciA9IHRydWU7CiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTsKICAgICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgbm9kZUluZGVudCk7CiAgICAgIGNvbXBvc2VOb2RlKHN0YXRlLCBub2RlSW5kZW50LCBDT05URVhUX0ZMT1dfSU4sIGZhbHNlLCB0cnVlKTsKICAgICAgdmFsdWVOb2RlID0gc3RhdGUucmVzdWx0OwogICAgfQoKICAgIGlmIChpc01hcHBpbmcpIHsKICAgICAgc3RvcmVNYXBwaW5nUGFpcihzdGF0ZSwgX3Jlc3VsdCwgb3ZlcnJpZGFibGVLZXlzLCBrZXlUYWcsIGtleU5vZGUsIHZhbHVlTm9kZSk7CiAgICB9IGVsc2UgaWYgKGlzUGFpcikgewogICAgICBfcmVzdWx0LnB1c2goc3RvcmVNYXBwaW5nUGFpcihzdGF0ZSwgbnVsbCwgb3ZlcnJpZGFibGVLZXlzLCBrZXlUYWcsIGtleU5vZGUsIHZhbHVlTm9kZSkpOwogICAgfSBlbHNlIHsKICAgICAgX3Jlc3VsdC5wdXNoKGtleU5vZGUpOwogICAgfQoKICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIG5vZGVJbmRlbnQpOwoKICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7CgogICAgaWYgKGNoID09PSAweDJDLyogLCAqLykgewogICAgICByZWFkTmV4dCA9IHRydWU7CiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTsKICAgIH0gZWxzZSB7CiAgICAgIHJlYWROZXh0ID0gZmFsc2U7CiAgICB9CiAgfQoKICB0aHJvd0Vycm9yKHN0YXRlLCAndW5leHBlY3RlZCBlbmQgb2YgdGhlIHN0cmVhbSB3aXRoaW4gYSBmbG93IGNvbGxlY3Rpb24nKTsKfQoKZnVuY3Rpb24gcmVhZEJsb2NrU2NhbGFyKHN0YXRlLCBub2RlSW5kZW50KSB7CiAgdmFyIGNhcHR1cmVTdGFydCwKICAgICAgZm9sZGluZywKICAgICAgY2hvbXBpbmcgICAgICAgPSBDSE9NUElOR19DTElQLAogICAgICBkaWRSZWFkQ29udGVudCA9IGZhbHNlLAogICAgICBkZXRlY3RlZEluZGVudCA9IGZhbHNlLAogICAgICB0ZXh0SW5kZW50ICAgICA9IG5vZGVJbmRlbnQsCiAgICAgIGVtcHR5TGluZXMgICAgID0gMCwKICAgICAgYXRNb3JlSW5kZW50ZWQgPSBmYWxzZSwKICAgICAgdG1wLAogICAgICBjaDsKCiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTsKCiAgaWYgKGNoID09PSAweDdDLyogfCAqLykgewogICAgZm9sZGluZyA9IGZhbHNlOwogIH0gZWxzZSBpZiAoY2ggPT09IDB4M0UvKiA+ICovKSB7CiAgICBmb2xkaW5nID0gdHJ1ZTsKICB9IGVsc2UgewogICAgcmV0dXJuIGZhbHNlOwogIH0KCiAgc3RhdGUua2luZCA9ICdzY2FsYXInOwogIHN0YXRlLnJlc3VsdCA9ICcnOwoKICB3aGlsZSAoY2ggIT09IDApIHsKICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTsKCiAgICBpZiAoY2ggPT09IDB4MkIvKiArICovIHx8IGNoID09PSAweDJELyogLSAqLykgewogICAgICBpZiAoQ0hPTVBJTkdfQ0xJUCA9PT0gY2hvbXBpbmcpIHsKICAgICAgICBjaG9tcGluZyA9IChjaCA9PT0gMHgyQi8qICsgKi8pID8gQ0hPTVBJTkdfS0VFUCA6IENIT01QSU5HX1NUUklQOwogICAgICB9IGVsc2UgewogICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdyZXBlYXQgb2YgYSBjaG9tcGluZyBtb2RlIGlkZW50aWZpZXInKTsKICAgICAgfQoKICAgIH0gZWxzZSBpZiAoKHRtcCA9IGZyb21EZWNpbWFsQ29kZShjaCkpID49IDApIHsKICAgICAgaWYgKHRtcCA9PT0gMCkgewogICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdiYWQgZXhwbGljaXQgaW5kZW50YXRpb24gd2lkdGggb2YgYSBibG9jayBzY2FsYXI7IGl0IGNhbm5vdCBiZSBsZXNzIHRoYW4gb25lJyk7CiAgICAgIH0gZWxzZSBpZiAoIWRldGVjdGVkSW5kZW50KSB7CiAgICAgICAgdGV4dEluZGVudCA9IG5vZGVJbmRlbnQgKyB0bXAgLSAxOwogICAgICAgIGRldGVjdGVkSW5kZW50ID0gdHJ1ZTsKICAgICAgfSBlbHNlIHsKICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAncmVwZWF0IG9mIGFuIGluZGVudGF0aW9uIHdpZHRoIGlkZW50aWZpZXInKTsKICAgICAgfQoKICAgIH0gZWxzZSB7CiAgICAgIGJyZWFrOwogICAgfQogIH0KCiAgaWYgKGlzX1dISVRFX1NQQUNFKGNoKSkgewogICAgZG8geyBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7IH0KICAgIHdoaWxlIChpc19XSElURV9TUEFDRShjaCkpOwoKICAgIGlmIChjaCA9PT0gMHgyMy8qICMgKi8pIHsKICAgICAgZG8geyBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7IH0KICAgICAgd2hpbGUgKCFpc19FT0woY2gpICYmIChjaCAhPT0gMCkpOwogICAgfQogIH0KCiAgd2hpbGUgKGNoICE9PSAwKSB7CiAgICByZWFkTGluZUJyZWFrKHN0YXRlKTsKICAgIHN0YXRlLmxpbmVJbmRlbnQgPSAwOwoKICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7CgogICAgd2hpbGUgKCghZGV0ZWN0ZWRJbmRlbnQgfHwgc3RhdGUubGluZUluZGVudCA8IHRleHRJbmRlbnQpICYmCiAgICAgICAgICAgKGNoID09PSAweDIwLyogU3BhY2UgKi8pKSB7CiAgICAgIHN0YXRlLmxpbmVJbmRlbnQrKzsKICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pOwogICAgfQoKICAgIGlmICghZGV0ZWN0ZWRJbmRlbnQgJiYgc3RhdGUubGluZUluZGVudCA+IHRleHRJbmRlbnQpIHsKICAgICAgdGV4dEluZGVudCA9IHN0YXRlLmxpbmVJbmRlbnQ7CiAgICB9CgogICAgaWYgKGlzX0VPTChjaCkpIHsKICAgICAgZW1wdHlMaW5lcysrOwogICAgICBjb250aW51ZTsKICAgIH0KICAgIGlmIChzdGF0ZS5saW5lSW5kZW50IDwgdGV4dEluZGVudCkgewogICAgICBpZiAoY2hvbXBpbmcgPT09IENIT01QSU5HX0tFRVApIHsKICAgICAgICBzdGF0ZS5yZXN1bHQgKz0gY29tbW9uLnJlcGVhdCgnXG4nLCBkaWRSZWFkQ29udGVudCA/IDEgKyBlbXB0eUxpbmVzIDogZW1wdHlMaW5lcyk7CiAgICAgIH0gZWxzZSBpZiAoY2hvbXBpbmcgPT09IENIT01QSU5HX0NMSVApIHsKICAgICAgICBpZiAoZGlkUmVhZENvbnRlbnQpIHsgLy8gaS5lLiBvbmx5IGlmIHRoZSBzY2FsYXIgaXMgbm90IGVtcHR5LgogICAgICAgICAgc3RhdGUucmVzdWx0ICs9ICdcbic7CiAgICAgICAgfQogICAgICB9CiAgICAgIGJyZWFrOwogICAgfQogICAgaWYgKGZvbGRpbmcpIHsKICAgICAgaWYgKGlzX1dISVRFX1NQQUNFKGNoKSkgewogICAgICAgIGF0TW9yZUluZGVudGVkID0gdHJ1ZTsKICAgICAgICBzdGF0ZS5yZXN1bHQgKz0gY29tbW9uLnJlcGVhdCgnXG4nLCBkaWRSZWFkQ29udGVudCA/IDEgKyBlbXB0eUxpbmVzIDogZW1wdHlMaW5lcyk7CiAgICAgIH0gZWxzZSBpZiAoYXRNb3JlSW5kZW50ZWQpIHsKICAgICAgICBhdE1vcmVJbmRlbnRlZCA9IGZhbHNlOwogICAgICAgIHN0YXRlLnJlc3VsdCArPSBjb21tb24ucmVwZWF0KCdcbicsIGVtcHR5TGluZXMgKyAxKTsKICAgICAgfSBlbHNlIGlmIChlbXB0eUxpbmVzID09PSAwKSB7CiAgICAgICAgaWYgKGRpZFJlYWRDb250ZW50KSB7IC8vIGkuZS4gb25seSBpZiB3ZSBoYXZlIGFscmVhZHkgcmVhZCBzb21lIHNjYWxhciBjb250ZW50LgogICAgICAgICAgc3RhdGUucmVzdWx0ICs9ICcgJzsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc3RhdGUucmVzdWx0ICs9IGNvbW1vbi5yZXBlYXQoJ1xuJywgZW1wdHlMaW5lcyk7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIHN0YXRlLnJlc3VsdCArPSBjb21tb24ucmVwZWF0KCdcbicsIGRpZFJlYWRDb250ZW50ID8gMSArIGVtcHR5TGluZXMgOiBlbXB0eUxpbmVzKTsKICAgIH0KCiAgICBkaWRSZWFkQ29udGVudCA9IHRydWU7CiAgICBkZXRlY3RlZEluZGVudCA9IHRydWU7CiAgICBlbXB0eUxpbmVzID0gMDsKICAgIGNhcHR1cmVTdGFydCA9IHN0YXRlLnBvc2l0aW9uOwoKICAgIHdoaWxlICghaXNfRU9MKGNoKSAmJiAoY2ggIT09IDApKSB7CiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTsKICAgIH0KCiAgICBjYXB0dXJlU2VnbWVudChzdGF0ZSwgY2FwdHVyZVN0YXJ0LCBzdGF0ZS5wb3NpdGlvbiwgZmFsc2UpOwogIH0KCiAgcmV0dXJuIHRydWU7Cn0KCmZ1bmN0aW9uIHJlYWRCbG9ja1NlcXVlbmNlKHN0YXRlLCBub2RlSW5kZW50KSB7CiAgdmFyIF9saW5lLAogICAgICBfdGFnICAgICAgPSBzdGF0ZS50YWcsCiAgICAgIF9hbmNob3IgICA9IHN0YXRlLmFuY2hvciwKICAgICAgX3Jlc3VsdCAgID0gW10sCiAgICAgIGZvbGxvd2luZywKICAgICAgZGV0ZWN0ZWQgID0gZmFsc2UsCiAgICAgIGNoOwoKICBpZiAoc3RhdGUuYW5jaG9yICE9PSBudWxsKSB7CiAgICBzdGF0ZS5hbmNob3JNYXBbc3RhdGUuYW5jaG9yXSA9IF9yZXN1bHQ7CiAgfQoKICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pOwoKICB3aGlsZSAoY2ggIT09IDApIHsKCiAgICBpZiAoY2ggIT09IDB4MkQvKiAtICovKSB7CiAgICAgIGJyZWFrOwogICAgfQoKICAgIGZvbGxvd2luZyA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24gKyAxKTsKCiAgICBpZiAoIWlzX1dTX09SX0VPTChmb2xsb3dpbmcpKSB7CiAgICAgIGJyZWFrOwogICAgfQoKICAgIGRldGVjdGVkID0gdHJ1ZTsKICAgIHN0YXRlLnBvc2l0aW9uKys7CgogICAgaWYgKHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKSkgewogICAgICBpZiAoc3RhdGUubGluZUluZGVudCA8PSBub2RlSW5kZW50KSB7CiAgICAgICAgX3Jlc3VsdC5wdXNoKG51bGwpOwogICAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7CiAgICAgICAgY29udGludWU7CiAgICAgIH0KICAgIH0KCiAgICBfbGluZSA9IHN0YXRlLmxpbmU7CiAgICBjb21wb3NlTm9kZShzdGF0ZSwgbm9kZUluZGVudCwgQ09OVEVYVF9CTE9DS19JTiwgZmFsc2UsIHRydWUpOwogICAgX3Jlc3VsdC5wdXNoKHN0YXRlLnJlc3VsdCk7CiAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCAtMSk7CgogICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTsKCiAgICBpZiAoKHN0YXRlLmxpbmUgPT09IF9saW5lIHx8IHN0YXRlLmxpbmVJbmRlbnQgPiBub2RlSW5kZW50KSAmJiAoY2ggIT09IDApKSB7CiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdiYWQgaW5kZW50YXRpb24gb2YgYSBzZXF1ZW5jZSBlbnRyeScpOwogICAgfSBlbHNlIGlmIChzdGF0ZS5saW5lSW5kZW50IDwgbm9kZUluZGVudCkgewogICAgICBicmVhazsKICAgIH0KICB9CgogIGlmIChkZXRlY3RlZCkgewogICAgc3RhdGUudGFnID0gX3RhZzsKICAgIHN0YXRlLmFuY2hvciA9IF9hbmNob3I7CiAgICBzdGF0ZS5raW5kID0gJ3NlcXVlbmNlJzsKICAgIHN0YXRlLnJlc3VsdCA9IF9yZXN1bHQ7CiAgICByZXR1cm4gdHJ1ZTsKICB9CiAgcmV0dXJuIGZhbHNlOwp9CgpmdW5jdGlvbiByZWFkQmxvY2tNYXBwaW5nKHN0YXRlLCBub2RlSW5kZW50LCBmbG93SW5kZW50KSB7CiAgdmFyIGZvbGxvd2luZywKICAgICAgYWxsb3dDb21wYWN0LAogICAgICBfbGluZSwKICAgICAgX3BvcywKICAgICAgX3RhZyAgICAgICAgICA9IHN0YXRlLnRhZywKICAgICAgX2FuY2hvciAgICAgICA9IHN0YXRlLmFuY2hvciwKICAgICAgX3Jlc3VsdCAgICAgICA9IHt9LAogICAgICBvdmVycmlkYWJsZUtleXMgPSB7fSwKICAgICAga2V5VGFnICAgICAgICA9IG51bGwsCiAgICAgIGtleU5vZGUgICAgICAgPSBudWxsLAogICAgICB2YWx1ZU5vZGUgICAgID0gbnVsbCwKICAgICAgYXRFeHBsaWNpdEtleSA9IGZhbHNlLAogICAgICBkZXRlY3RlZCAgICAgID0gZmFsc2UsCiAgICAgIGNoOwoKICBpZiAoc3RhdGUuYW5jaG9yICE9PSBudWxsKSB7CiAgICBzdGF0ZS5hbmNob3JNYXBbc3RhdGUuYW5jaG9yXSA9IF9yZXN1bHQ7CiAgfQoKICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pOwoKICB3aGlsZSAoY2ggIT09IDApIHsKICAgIGZvbGxvd2luZyA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24gKyAxKTsKICAgIF9saW5lID0gc3RhdGUubGluZTsgLy8gU2F2ZSB0aGUgY3VycmVudCBsaW5lLgogICAgX3BvcyA9IHN0YXRlLnBvc2l0aW9uOwogICAgaWYgKChjaCA9PT0gMHgzRi8qID8gKi8gfHwgY2ggPT09IDB4M0EvKiA6ICovKSAmJiBpc19XU19PUl9FT0woZm9sbG93aW5nKSkgewoKICAgICAgaWYgKGNoID09PSAweDNGLyogPyAqLykgewogICAgICAgIGlmIChhdEV4cGxpY2l0S2V5KSB7CiAgICAgICAgICBzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBfcmVzdWx0LCBvdmVycmlkYWJsZUtleXMsIGtleVRhZywga2V5Tm9kZSwgbnVsbCk7CiAgICAgICAgICBrZXlUYWcgPSBrZXlOb2RlID0gdmFsdWVOb2RlID0gbnVsbDsKICAgICAgICB9CgogICAgICAgIGRldGVjdGVkID0gdHJ1ZTsKICAgICAgICBhdEV4cGxpY2l0S2V5ID0gdHJ1ZTsKICAgICAgICBhbGxvd0NvbXBhY3QgPSB0cnVlOwoKICAgICAgfSBlbHNlIGlmIChhdEV4cGxpY2l0S2V5KSB7CiAgICAgICAgYXRFeHBsaWNpdEtleSA9IGZhbHNlOwogICAgICAgIGFsbG93Q29tcGFjdCA9IHRydWU7CgogICAgICB9IGVsc2UgewogICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdpbmNvbXBsZXRlIGV4cGxpY2l0IG1hcHBpbmcgcGFpcjsgYSBrZXkgbm9kZSBpcyBtaXNzZWQ7IG9yIGZvbGxvd2VkIGJ5IGEgbm9uLXRhYnVsYXRlZCBlbXB0eSBsaW5lJyk7CiAgICAgIH0KCiAgICAgIHN0YXRlLnBvc2l0aW9uICs9IDE7CiAgICAgIGNoID0gZm9sbG93aW5nOwogICAgfSBlbHNlIGlmIChjb21wb3NlTm9kZShzdGF0ZSwgZmxvd0luZGVudCwgQ09OVEVYVF9GTE9XX09VVCwgZmFsc2UsIHRydWUpKSB7CgogICAgICBpZiAoc3RhdGUubGluZSA9PT0gX2xpbmUpIHsKICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pOwoKICAgICAgICB3aGlsZSAoaXNfV0hJVEVfU1BBQ0UoY2gpKSB7CiAgICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7CiAgICAgICAgfQoKICAgICAgICBpZiAoY2ggPT09IDB4M0EvKiA6ICovKSB7CiAgICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7CgogICAgICAgICAgaWYgKCFpc19XU19PUl9FT0woY2gpKSB7CiAgICAgICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdhIHdoaXRlc3BhY2UgY2hhcmFjdGVyIGlzIGV4cGVjdGVkIGFmdGVyIHRoZSBrZXktdmFsdWUgc2VwYXJhdG9yIHdpdGhpbiBhIGJsb2NrIG1hcHBpbmcnKTsKICAgICAgICAgIH0KCiAgICAgICAgICBpZiAoYXRFeHBsaWNpdEtleSkgewogICAgICAgICAgICBzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBfcmVzdWx0LCBvdmVycmlkYWJsZUtleXMsIGtleVRhZywga2V5Tm9kZSwgbnVsbCk7CiAgICAgICAgICAgIGtleVRhZyA9IGtleU5vZGUgPSB2YWx1ZU5vZGUgPSBudWxsOwogICAgICAgICAgfQoKICAgICAgICAgIGRldGVjdGVkID0gdHJ1ZTsKICAgICAgICAgIGF0RXhwbGljaXRLZXkgPSBmYWxzZTsKICAgICAgICAgIGFsbG93Q29tcGFjdCA9IGZhbHNlOwogICAgICAgICAga2V5VGFnID0gc3RhdGUudGFnOwogICAgICAgICAga2V5Tm9kZSA9IHN0YXRlLnJlc3VsdDsKCiAgICAgICAgfSBlbHNlIGlmIChkZXRlY3RlZCkgewogICAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2NhbiBub3QgcmVhZCBhbiBpbXBsaWNpdCBtYXBwaW5nIHBhaXI7IGEgY29sb24gaXMgbWlzc2VkJyk7CgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdGF0ZS50YWcgPSBfdGFnOwogICAgICAgICAgc3RhdGUuYW5jaG9yID0gX2FuY2hvcjsKICAgICAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIHRoZSByZXN1bHQgb2YgYGNvbXBvc2VOb2RlYC4KICAgICAgICB9CgogICAgICB9IGVsc2UgaWYgKGRldGVjdGVkKSB7CiAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2NhbiBub3QgcmVhZCBhIGJsb2NrIG1hcHBpbmcgZW50cnk7IGEgbXVsdGlsaW5lIGtleSBtYXkgbm90IGJlIGFuIGltcGxpY2l0IGtleScpOwoKICAgICAgfSBlbHNlIHsKICAgICAgICBzdGF0ZS50YWcgPSBfdGFnOwogICAgICAgIHN0YXRlLmFuY2hvciA9IF9hbmNob3I7CiAgICAgICAgcmV0dXJuIHRydWU7IC8vIEtlZXAgdGhlIHJlc3VsdCBvZiBgY29tcG9zZU5vZGVgLgogICAgICB9CgogICAgfSBlbHNlIHsKICAgICAgYnJlYWs7IC8vIFJlYWRpbmcgaXMgZG9uZS4gR28gdG8gdGhlIGVwaWxvZ3VlLgogICAgfQogICAgaWYgKHN0YXRlLmxpbmUgPT09IF9saW5lIHx8IHN0YXRlLmxpbmVJbmRlbnQgPiBub2RlSW5kZW50KSB7CiAgICAgIGlmIChjb21wb3NlTm9kZShzdGF0ZSwgbm9kZUluZGVudCwgQ09OVEVYVF9CTE9DS19PVVQsIHRydWUsIGFsbG93Q29tcGFjdCkpIHsKICAgICAgICBpZiAoYXRFeHBsaWNpdEtleSkgewogICAgICAgICAga2V5Tm9kZSA9IHN0YXRlLnJlc3VsdDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgdmFsdWVOb2RlID0gc3RhdGUucmVzdWx0OwogICAgICAgIH0KICAgICAgfQoKICAgICAgaWYgKCFhdEV4cGxpY2l0S2V5KSB7CiAgICAgICAgc3RvcmVNYXBwaW5nUGFpcihzdGF0ZSwgX3Jlc3VsdCwgb3ZlcnJpZGFibGVLZXlzLCBrZXlUYWcsIGtleU5vZGUsIHZhbHVlTm9kZSwgX2xpbmUsIF9wb3MpOwogICAgICAgIGtleVRhZyA9IGtleU5vZGUgPSB2YWx1ZU5vZGUgPSBudWxsOwogICAgICB9CgogICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCAtMSk7CiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7CiAgICB9CgogICAgaWYgKHN0YXRlLmxpbmVJbmRlbnQgPiBub2RlSW5kZW50ICYmIChjaCAhPT0gMCkpIHsKICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2JhZCBpbmRlbnRhdGlvbiBvZiBhIG1hcHBpbmcgZW50cnknKTsKICAgIH0gZWxzZSBpZiAoc3RhdGUubGluZUluZGVudCA8IG5vZGVJbmRlbnQpIHsKICAgICAgYnJlYWs7CiAgICB9CiAgfQogIGlmIChhdEV4cGxpY2l0S2V5KSB7CiAgICBzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBfcmVzdWx0LCBvdmVycmlkYWJsZUtleXMsIGtleVRhZywga2V5Tm9kZSwgbnVsbCk7CiAgfQogIGlmIChkZXRlY3RlZCkgewogICAgc3RhdGUudGFnID0gX3RhZzsKICAgIHN0YXRlLmFuY2hvciA9IF9hbmNob3I7CiAgICBzdGF0ZS5raW5kID0gJ21hcHBpbmcnOwogICAgc3RhdGUucmVzdWx0ID0gX3Jlc3VsdDsKICB9CgogIHJldHVybiBkZXRlY3RlZDsKfQoKZnVuY3Rpb24gcmVhZFRhZ1Byb3BlcnR5KHN0YXRlKSB7CiAgdmFyIF9wb3NpdGlvbiwKICAgICAgaXNWZXJiYXRpbSA9IGZhbHNlLAogICAgICBpc05hbWVkICAgID0gZmFsc2UsCiAgICAgIHRhZ0hhbmRsZSwKICAgICAgdGFnTmFtZSwKICAgICAgY2g7CgogIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7CgogIGlmIChjaCAhPT0gMHgyMS8qICEgKi8pIHJldHVybiBmYWxzZTsKCiAgaWYgKHN0YXRlLnRhZyAhPT0gbnVsbCkgewogICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2R1cGxpY2F0aW9uIG9mIGEgdGFnIHByb3BlcnR5Jyk7CiAgfQoKICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7CgogIGlmIChjaCA9PT0gMHgzQy8qIDwgKi8pIHsKICAgIGlzVmVyYmF0aW0gPSB0cnVlOwogICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pOwoKICB9IGVsc2UgaWYgKGNoID09PSAweDIxLyogISAqLykgewogICAgaXNOYW1lZCA9IHRydWU7CiAgICB0YWdIYW5kbGUgPSAnISEnOwogICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pOwoKICB9IGVsc2UgewogICAgdGFnSGFuZGxlID0gJyEnOwogIH0KCiAgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb247CgogIGlmIChpc1ZlcmJhdGltKSB7CiAgICBkbyB7IGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTsgfQogICAgd2hpbGUgKGNoICE9PSAwICYmIGNoICE9PSAweDNFLyogPiAqLyk7CgogICAgaWYgKHN0YXRlLnBvc2l0aW9uIDwgc3RhdGUubGVuZ3RoKSB7CiAgICAgIHRhZ05hbWUgPSBzdGF0ZS5pbnB1dC5zbGljZShfcG9zaXRpb24sIHN0YXRlLnBvc2l0aW9uKTsKICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pOwogICAgfSBlbHNlIHsKICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3VuZXhwZWN0ZWQgZW5kIG9mIHRoZSBzdHJlYW0gd2l0aGluIGEgdmVyYmF0aW0gdGFnJyk7CiAgICB9CiAgfSBlbHNlIHsKICAgIHdoaWxlIChjaCAhPT0gMCAmJiAhaXNfV1NfT1JfRU9MKGNoKSkgewoKICAgICAgaWYgKGNoID09PSAweDIxLyogISAqLykgewogICAgICAgIGlmICghaXNOYW1lZCkgewogICAgICAgICAgdGFnSGFuZGxlID0gc3RhdGUuaW5wdXQuc2xpY2UoX3Bvc2l0aW9uIC0gMSwgc3RhdGUucG9zaXRpb24gKyAxKTsKCiAgICAgICAgICBpZiAoIVBBVFRFUk5fVEFHX0hBTkRMRS50ZXN0KHRhZ0hhbmRsZSkpIHsKICAgICAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ25hbWVkIHRhZyBoYW5kbGUgY2Fubm90IGNvbnRhaW4gc3VjaCBjaGFyYWN0ZXJzJyk7CiAgICAgICAgICB9CgogICAgICAgICAgaXNOYW1lZCA9IHRydWU7CiAgICAgICAgICBfcG9zaXRpb24gPSBzdGF0ZS5wb3NpdGlvbiArIDE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd0YWcgc3VmZml4IGNhbm5vdCBjb250YWluIGV4Y2xhbWF0aW9uIG1hcmtzJyk7CiAgICAgICAgfQogICAgICB9CgogICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7CiAgICB9CgogICAgdGFnTmFtZSA9IHN0YXRlLmlucHV0LnNsaWNlKF9wb3NpdGlvbiwgc3RhdGUucG9zaXRpb24pOwoKICAgIGlmIChQQVRURVJOX0ZMT1dfSU5ESUNBVE9SUy50ZXN0KHRhZ05hbWUpKSB7CiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd0YWcgc3VmZml4IGNhbm5vdCBjb250YWluIGZsb3cgaW5kaWNhdG9yIGNoYXJhY3RlcnMnKTsKICAgIH0KICB9CgogIGlmICh0YWdOYW1lICYmICFQQVRURVJOX1RBR19VUkkudGVzdCh0YWdOYW1lKSkgewogICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3RhZyBuYW1lIGNhbm5vdCBjb250YWluIHN1Y2ggY2hhcmFjdGVyczogJyArIHRhZ05hbWUpOwogIH0KCiAgaWYgKGlzVmVyYmF0aW0pIHsKICAgIHN0YXRlLnRhZyA9IHRhZ05hbWU7CgogIH0gZWxzZSBpZiAoX2hhc093blByb3BlcnR5LmNhbGwoc3RhdGUudGFnTWFwLCB0YWdIYW5kbGUpKSB7CiAgICBzdGF0ZS50YWcgPSBzdGF0ZS50YWdNYXBbdGFnSGFuZGxlXSArIHRhZ05hbWU7CgogIH0gZWxzZSBpZiAodGFnSGFuZGxlID09PSAnIScpIHsKICAgIHN0YXRlLnRhZyA9ICchJyArIHRhZ05hbWU7CgogIH0gZWxzZSBpZiAodGFnSGFuZGxlID09PSAnISEnKSB7CiAgICBzdGF0ZS50YWcgPSAndGFnOnlhbWwub3JnLDIwMDI6JyArIHRhZ05hbWU7CgogIH0gZWxzZSB7CiAgICB0aHJvd0Vycm9yKHN0YXRlLCAndW5kZWNsYXJlZCB0YWcgaGFuZGxlICInICsgdGFnSGFuZGxlICsgJyInKTsKICB9CgogIHJldHVybiB0cnVlOwp9CgpmdW5jdGlvbiByZWFkQW5jaG9yUHJvcGVydHkoc3RhdGUpIHsKICB2YXIgX3Bvc2l0aW9uLAogICAgICBjaDsKCiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTsKCiAgaWYgKGNoICE9PSAweDI2LyogJiAqLykgcmV0dXJuIGZhbHNlOwoKICBpZiAoc3RhdGUuYW5jaG9yICE9PSBudWxsKSB7CiAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZHVwbGljYXRpb24gb2YgYW4gYW5jaG9yIHByb3BlcnR5Jyk7CiAgfQoKICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7CiAgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb247CgogIHdoaWxlIChjaCAhPT0gMCAmJiAhaXNfV1NfT1JfRU9MKGNoKSAmJiAhaXNfRkxPV19JTkRJQ0FUT1IoY2gpKSB7CiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7CiAgfQoKICBpZiAoc3RhdGUucG9zaXRpb24gPT09IF9wb3NpdGlvbikgewogICAgdGhyb3dFcnJvcihzdGF0ZSwgJ25hbWUgb2YgYW4gYW5jaG9yIG5vZGUgbXVzdCBjb250YWluIGF0IGxlYXN0IG9uZSBjaGFyYWN0ZXInKTsKICB9CgogIHN0YXRlLmFuY2hvciA9IHN0YXRlLmlucHV0LnNsaWNlKF9wb3NpdGlvbiwgc3RhdGUucG9zaXRpb24pOwogIHJldHVybiB0cnVlOwp9CgpmdW5jdGlvbiByZWFkQWxpYXMoc3RhdGUpIHsKICB2YXIgX3Bvc2l0aW9uLCBhbGlhcywKICAgICAgY2g7CgogIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7CgogIGlmIChjaCAhPT0gMHgyQS8qICogKi8pIHJldHVybiBmYWxzZTsKCiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pOwogIF9wb3NpdGlvbiA9IHN0YXRlLnBvc2l0aW9uOwoKICB3aGlsZSAoY2ggIT09IDAgJiYgIWlzX1dTX09SX0VPTChjaCkgJiYgIWlzX0ZMT1dfSU5ESUNBVE9SKGNoKSkgewogICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pOwogIH0KCiAgaWYgKHN0YXRlLnBvc2l0aW9uID09PSBfcG9zaXRpb24pIHsKICAgIHRocm93RXJyb3Ioc3RhdGUsICduYW1lIG9mIGFuIGFsaWFzIG5vZGUgbXVzdCBjb250YWluIGF0IGxlYXN0IG9uZSBjaGFyYWN0ZXInKTsKICB9CgogIGFsaWFzID0gc3RhdGUuaW5wdXQuc2xpY2UoX3Bvc2l0aW9uLCBzdGF0ZS5wb3NpdGlvbik7CgogIGlmICghc3RhdGUuYW5jaG9yTWFwLmhhc093blByb3BlcnR5KGFsaWFzKSkgewogICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3VuaWRlbnRpZmllZCBhbGlhcyAiJyArIGFsaWFzICsgJyInKTsKICB9CgogIHN0YXRlLnJlc3VsdCA9IHN0YXRlLmFuY2hvck1hcFthbGlhc107CiAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpOwogIHJldHVybiB0cnVlOwp9CgpmdW5jdGlvbiBjb21wb3NlTm9kZShzdGF0ZSwgcGFyZW50SW5kZW50LCBub2RlQ29udGV4dCwgYWxsb3dUb1NlZWssIGFsbG93Q29tcGFjdCkgewogIHZhciBhbGxvd0Jsb2NrU3R5bGVzLAogICAgICBhbGxvd0Jsb2NrU2NhbGFycywKICAgICAgYWxsb3dCbG9ja0NvbGxlY3Rpb25zLAogICAgICBpbmRlbnRTdGF0dXMgPSAxLCAvLyAxOiB0aGlzPnBhcmVudCwgMDogdGhpcz1wYXJlbnQsIC0xOiB0aGlzPHBhcmVudAogICAgICBhdE5ld0xpbmUgID0gZmFsc2UsCiAgICAgIGhhc0NvbnRlbnQgPSBmYWxzZSwKICAgICAgdHlwZUluZGV4LAogICAgICB0eXBlUXVhbnRpdHksCiAgICAgIHR5cGUsCiAgICAgIGZsb3dJbmRlbnQsCiAgICAgIGJsb2NrSW5kZW50OwoKICBpZiAoc3RhdGUubGlzdGVuZXIgIT09IG51bGwpIHsKICAgIHN0YXRlLmxpc3RlbmVyKCdvcGVuJywgc3RhdGUpOwogIH0KCiAgc3RhdGUudGFnICAgID0gbnVsbDsKICBzdGF0ZS5hbmNob3IgPSBudWxsOwogIHN0YXRlLmtpbmQgICA9IG51bGw7CiAgc3RhdGUucmVzdWx0ID0gbnVsbDsKCiAgYWxsb3dCbG9ja1N0eWxlcyA9IGFsbG93QmxvY2tTY2FsYXJzID0gYWxsb3dCbG9ja0NvbGxlY3Rpb25zID0KICAgIENPTlRFWFRfQkxPQ0tfT1VUID09PSBub2RlQ29udGV4dCB8fAogICAgQ09OVEVYVF9CTE9DS19JTiAgPT09IG5vZGVDb250ZXh0OwoKICBpZiAoYWxsb3dUb1NlZWspIHsKICAgIGlmIChza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCAtMSkpIHsKICAgICAgYXROZXdMaW5lID0gdHJ1ZTsKCiAgICAgIGlmIChzdGF0ZS5saW5lSW5kZW50ID4gcGFyZW50SW5kZW50KSB7CiAgICAgICAgaW5kZW50U3RhdHVzID0gMTsKICAgICAgfSBlbHNlIGlmIChzdGF0ZS5saW5lSW5kZW50ID09PSBwYXJlbnRJbmRlbnQpIHsKICAgICAgICBpbmRlbnRTdGF0dXMgPSAwOwogICAgICB9IGVsc2UgaWYgKHN0YXRlLmxpbmVJbmRlbnQgPCBwYXJlbnRJbmRlbnQpIHsKICAgICAgICBpbmRlbnRTdGF0dXMgPSAtMTsKICAgICAgfQogICAgfQogIH0KCiAgaWYgKGluZGVudFN0YXR1cyA9PT0gMSkgewogICAgd2hpbGUgKHJlYWRUYWdQcm9wZXJ0eShzdGF0ZSkgfHwgcmVhZEFuY2hvclByb3BlcnR5KHN0YXRlKSkgewogICAgICBpZiAoc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpKSB7CiAgICAgICAgYXROZXdMaW5lID0gdHJ1ZTsKICAgICAgICBhbGxvd0Jsb2NrQ29sbGVjdGlvbnMgPSBhbGxvd0Jsb2NrU3R5bGVzOwoKICAgICAgICBpZiAoc3RhdGUubGluZUluZGVudCA+IHBhcmVudEluZGVudCkgewogICAgICAgICAgaW5kZW50U3RhdHVzID0gMTsKICAgICAgICB9IGVsc2UgaWYgKHN0YXRlLmxpbmVJbmRlbnQgPT09IHBhcmVudEluZGVudCkgewogICAgICAgICAgaW5kZW50U3RhdHVzID0gMDsKICAgICAgICB9IGVsc2UgaWYgKHN0YXRlLmxpbmVJbmRlbnQgPCBwYXJlbnRJbmRlbnQpIHsKICAgICAgICAgIGluZGVudFN0YXR1cyA9IC0xOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBhbGxvd0Jsb2NrQ29sbGVjdGlvbnMgPSBmYWxzZTsKICAgICAgfQogICAgfQogIH0KCiAgaWYgKGFsbG93QmxvY2tDb2xsZWN0aW9ucykgewogICAgYWxsb3dCbG9ja0NvbGxlY3Rpb25zID0gYXROZXdMaW5lIHx8IGFsbG93Q29tcGFjdDsKICB9CgogIGlmIChpbmRlbnRTdGF0dXMgPT09IDEgfHwgQ09OVEVYVF9CTE9DS19PVVQgPT09IG5vZGVDb250ZXh0KSB7CiAgICBpZiAoQ09OVEVYVF9GTE9XX0lOID09PSBub2RlQ29udGV4dCB8fCBDT05URVhUX0ZMT1dfT1VUID09PSBub2RlQ29udGV4dCkgewogICAgICBmbG93SW5kZW50ID0gcGFyZW50SW5kZW50OwogICAgfSBlbHNlIHsKICAgICAgZmxvd0luZGVudCA9IHBhcmVudEluZGVudCArIDE7CiAgICB9CgogICAgYmxvY2tJbmRlbnQgPSBzdGF0ZS5wb3NpdGlvbiAtIHN0YXRlLmxpbmVTdGFydDsKCiAgICBpZiAoaW5kZW50U3RhdHVzID09PSAxKSB7CiAgICAgIGlmIChhbGxvd0Jsb2NrQ29sbGVjdGlvbnMgJiYKICAgICAgICAgIChyZWFkQmxvY2tTZXF1ZW5jZShzdGF0ZSwgYmxvY2tJbmRlbnQpIHx8CiAgICAgICAgICAgcmVhZEJsb2NrTWFwcGluZyhzdGF0ZSwgYmxvY2tJbmRlbnQsIGZsb3dJbmRlbnQpKSB8fAogICAgICAgICAgcmVhZEZsb3dDb2xsZWN0aW9uKHN0YXRlLCBmbG93SW5kZW50KSkgewogICAgICAgIGhhc0NvbnRlbnQgPSB0cnVlOwogICAgICB9IGVsc2UgewogICAgICAgIGlmICgoYWxsb3dCbG9ja1NjYWxhcnMgJiYgcmVhZEJsb2NrU2NhbGFyKHN0YXRlLCBmbG93SW5kZW50KSkgfHwKICAgICAgICAgICAgcmVhZFNpbmdsZVF1b3RlZFNjYWxhcihzdGF0ZSwgZmxvd0luZGVudCkgfHwKICAgICAgICAgICAgcmVhZERvdWJsZVF1b3RlZFNjYWxhcihzdGF0ZSwgZmxvd0luZGVudCkpIHsKICAgICAgICAgIGhhc0NvbnRlbnQgPSB0cnVlOwoKICAgICAgICB9IGVsc2UgaWYgKHJlYWRBbGlhcyhzdGF0ZSkpIHsKICAgICAgICAgIGhhc0NvbnRlbnQgPSB0cnVlOwoKICAgICAgICAgIGlmIChzdGF0ZS50YWcgIT09IG51bGwgfHwgc3RhdGUuYW5jaG9yICE9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdhbGlhcyBub2RlIHNob3VsZCBub3QgaGF2ZSBhbnkgcHJvcGVydGllcycpOwogICAgICAgICAgfQoKICAgICAgICB9IGVsc2UgaWYgKHJlYWRQbGFpblNjYWxhcihzdGF0ZSwgZmxvd0luZGVudCwgQ09OVEVYVF9GTE9XX0lOID09PSBub2RlQ29udGV4dCkpIHsKICAgICAgICAgIGhhc0NvbnRlbnQgPSB0cnVlOwoKICAgICAgICAgIGlmIChzdGF0ZS50YWcgPT09IG51bGwpIHsKICAgICAgICAgICAgc3RhdGUudGFnID0gJz8nOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKHN0YXRlLmFuY2hvciAhPT0gbnVsbCkgewogICAgICAgICAgc3RhdGUuYW5jaG9yTWFwW3N0YXRlLmFuY2hvcl0gPSBzdGF0ZS5yZXN1bHQ7CiAgICAgICAgfQogICAgICB9CiAgICB9IGVsc2UgaWYgKGluZGVudFN0YXR1cyA9PT0gMCkgewogICAgICBoYXNDb250ZW50ID0gYWxsb3dCbG9ja0NvbGxlY3Rpb25zICYmIHJlYWRCbG9ja1NlcXVlbmNlKHN0YXRlLCBibG9ja0luZGVudCk7CiAgICB9CiAgfQoKICBpZiAoc3RhdGUudGFnICE9PSBudWxsICYmIHN0YXRlLnRhZyAhPT0gJyEnKSB7CiAgICBpZiAoc3RhdGUudGFnID09PSAnPycpIHsKICAgICAgZm9yICh0eXBlSW5kZXggPSAwLCB0eXBlUXVhbnRpdHkgPSBzdGF0ZS5pbXBsaWNpdFR5cGVzLmxlbmd0aDsgdHlwZUluZGV4IDwgdHlwZVF1YW50aXR5OyB0eXBlSW5kZXggKz0gMSkgewogICAgICAgIHR5cGUgPSBzdGF0ZS5pbXBsaWNpdFR5cGVzW3R5cGVJbmRleF07CgogICAgICAgIGlmICh0eXBlLnJlc29sdmUoc3RhdGUucmVzdWx0KSkgeyAvLyBgc3RhdGUucmVzdWx0YCB1cGRhdGVkIGluIHJlc29sdmVyIGlmIG1hdGNoZWQKICAgICAgICAgIHN0YXRlLnJlc3VsdCA9IHR5cGUuY29uc3RydWN0KHN0YXRlLnJlc3VsdCk7CiAgICAgICAgICBzdGF0ZS50YWcgPSB0eXBlLnRhZzsKICAgICAgICAgIGlmIChzdGF0ZS5hbmNob3IgIT09IG51bGwpIHsKICAgICAgICAgICAgc3RhdGUuYW5jaG9yTWFwW3N0YXRlLmFuY2hvcl0gPSBzdGF0ZS5yZXN1bHQ7CiAgICAgICAgICB9CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIH0KICAgIH0gZWxzZSBpZiAoX2hhc093blByb3BlcnR5LmNhbGwoc3RhdGUudHlwZU1hcFtzdGF0ZS5raW5kIHx8ICdmYWxsYmFjayddLCBzdGF0ZS50YWcpKSB7CiAgICAgIHR5cGUgPSBzdGF0ZS50eXBlTWFwW3N0YXRlLmtpbmQgfHwgJ2ZhbGxiYWNrJ11bc3RhdGUudGFnXTsKCiAgICAgIGlmIChzdGF0ZS5yZXN1bHQgIT09IG51bGwgJiYgdHlwZS5raW5kICE9PSBzdGF0ZS5raW5kKSB7CiAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3VuYWNjZXB0YWJsZSBub2RlIGtpbmQgZm9yICE8JyArIHN0YXRlLnRhZyArICc+IHRhZzsgaXQgc2hvdWxkIGJlICInICsgdHlwZS5raW5kICsgJyIsIG5vdCAiJyArIHN0YXRlLmtpbmQgKyAnIicpOwogICAgICB9CgogICAgICBpZiAoIXR5cGUucmVzb2x2ZShzdGF0ZS5yZXN1bHQpKSB7IC8vIGBzdGF0ZS5yZXN1bHRgIHVwZGF0ZWQgaW4gcmVzb2x2ZXIgaWYgbWF0Y2hlZAogICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdjYW5ub3QgcmVzb2x2ZSBhIG5vZGUgd2l0aCAhPCcgKyBzdGF0ZS50YWcgKyAnPiBleHBsaWNpdCB0YWcnKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBzdGF0ZS5yZXN1bHQgPSB0eXBlLmNvbnN0cnVjdChzdGF0ZS5yZXN1bHQpOwogICAgICAgIGlmIChzdGF0ZS5hbmNob3IgIT09IG51bGwpIHsKICAgICAgICAgIHN0YXRlLmFuY2hvck1hcFtzdGF0ZS5hbmNob3JdID0gc3RhdGUucmVzdWx0OwogICAgICAgIH0KICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3Vua25vd24gdGFnICE8JyArIHN0YXRlLnRhZyArICc+Jyk7CiAgICB9CiAgfQoKICBpZiAoc3RhdGUubGlzdGVuZXIgIT09IG51bGwpIHsKICAgIHN0YXRlLmxpc3RlbmVyKCdjbG9zZScsIHN0YXRlKTsKICB9CiAgcmV0dXJuIHN0YXRlLnRhZyAhPT0gbnVsbCB8fCAgc3RhdGUuYW5jaG9yICE9PSBudWxsIHx8IGhhc0NvbnRlbnQ7Cn0KCmZ1bmN0aW9uIHJlYWREb2N1bWVudChzdGF0ZSkgewogIHZhciBkb2N1bWVudFN0YXJ0ID0gc3RhdGUucG9zaXRpb24sCiAgICAgIF9wb3NpdGlvbiwKICAgICAgZGlyZWN0aXZlTmFtZSwKICAgICAgZGlyZWN0aXZlQXJncywKICAgICAgaGFzRGlyZWN0aXZlcyA9IGZhbHNlLAogICAgICBjaDsKCiAgc3RhdGUudmVyc2lvbiA9IG51bGw7CiAgc3RhdGUuY2hlY2tMaW5lQnJlYWtzID0gc3RhdGUubGVnYWN5OwogIHN0YXRlLnRhZ01hcCA9IHt9OwogIHN0YXRlLmFuY2hvck1hcCA9IHt9OwoKICB3aGlsZSAoKGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbikpICE9PSAwKSB7CiAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCAtMSk7CgogICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTsKCiAgICBpZiAoc3RhdGUubGluZUluZGVudCA+IDAgfHwgY2ggIT09IDB4MjUvKiAlICovKSB7CiAgICAgIGJyZWFrOwogICAgfQoKICAgIGhhc0RpcmVjdGl2ZXMgPSB0cnVlOwogICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pOwogICAgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb247CgogICAgd2hpbGUgKGNoICE9PSAwICYmICFpc19XU19PUl9FT0woY2gpKSB7CiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTsKICAgIH0KCiAgICBkaXJlY3RpdmVOYW1lID0gc3RhdGUuaW5wdXQuc2xpY2UoX3Bvc2l0aW9uLCBzdGF0ZS5wb3NpdGlvbik7CiAgICBkaXJlY3RpdmVBcmdzID0gW107CgogICAgaWYgKGRpcmVjdGl2ZU5hbWUubGVuZ3RoIDwgMSkgewogICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZGlyZWN0aXZlIG5hbWUgbXVzdCBub3QgYmUgbGVzcyB0aGFuIG9uZSBjaGFyYWN0ZXIgaW4gbGVuZ3RoJyk7CiAgICB9CgogICAgd2hpbGUgKGNoICE9PSAwKSB7CiAgICAgIHdoaWxlIChpc19XSElURV9TUEFDRShjaCkpIHsKICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7CiAgICAgIH0KCiAgICAgIGlmIChjaCA9PT0gMHgyMy8qICMgKi8pIHsKICAgICAgICBkbyB7IGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTsgfQogICAgICAgIHdoaWxlIChjaCAhPT0gMCAmJiAhaXNfRU9MKGNoKSk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KCiAgICAgIGlmIChpc19FT0woY2gpKSBicmVhazsKCiAgICAgIF9wb3NpdGlvbiA9IHN0YXRlLnBvc2l0aW9uOwoKICAgICAgd2hpbGUgKGNoICE9PSAwICYmICFpc19XU19PUl9FT0woY2gpKSB7CiAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pOwogICAgICB9CgogICAgICBkaXJlY3RpdmVBcmdzLnB1c2goc3RhdGUuaW5wdXQuc2xpY2UoX3Bvc2l0aW9uLCBzdGF0ZS5wb3NpdGlvbikpOwogICAgfQoKICAgIGlmIChjaCAhPT0gMCkgcmVhZExpbmVCcmVhayhzdGF0ZSk7CgogICAgaWYgKF9oYXNPd25Qcm9wZXJ0eS5jYWxsKGRpcmVjdGl2ZUhhbmRsZXJzLCBkaXJlY3RpdmVOYW1lKSkgewogICAgICBkaXJlY3RpdmVIYW5kbGVyc1tkaXJlY3RpdmVOYW1lXShzdGF0ZSwgZGlyZWN0aXZlTmFtZSwgZGlyZWN0aXZlQXJncyk7CiAgICB9IGVsc2UgewogICAgICB0aHJvd1dhcm5pbmcoc3RhdGUsICd1bmtub3duIGRvY3VtZW50IGRpcmVjdGl2ZSAiJyArIGRpcmVjdGl2ZU5hbWUgKyAnIicpOwogICAgfQogIH0KCiAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpOwoKICBpZiAoc3RhdGUubGluZUluZGVudCA9PT0gMCAmJgogICAgICBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKSAgICAgPT09IDB4MkQvKiAtICovICYmCiAgICAgIHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24gKyAxKSA9PT0gMHgyRC8qIC0gKi8gJiYKICAgICAgc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDIpID09PSAweDJELyogLSAqLykgewogICAgc3RhdGUucG9zaXRpb24gKz0gMzsKICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTsKCiAgfSBlbHNlIGlmIChoYXNEaXJlY3RpdmVzKSB7CiAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZGlyZWN0aXZlcyBlbmQgbWFyayBpcyBleHBlY3RlZCcpOwogIH0KCiAgY29tcG9zZU5vZGUoc3RhdGUsIHN0YXRlLmxpbmVJbmRlbnQgLSAxLCBDT05URVhUX0JMT0NLX09VVCwgZmFsc2UsIHRydWUpOwogIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTsKCiAgaWYgKHN0YXRlLmNoZWNrTGluZUJyZWFrcyAmJgogICAgICBQQVRURVJOX05PTl9BU0NJSV9MSU5FX0JSRUFLUy50ZXN0KHN0YXRlLmlucHV0LnNsaWNlKGRvY3VtZW50U3RhcnQsIHN0YXRlLnBvc2l0aW9uKSkpIHsKICAgIHRocm93V2FybmluZyhzdGF0ZSwgJ25vbi1BU0NJSSBsaW5lIGJyZWFrcyBhcmUgaW50ZXJwcmV0ZWQgYXMgY29udGVudCcpOwogIH0KCiAgc3RhdGUuZG9jdW1lbnRzLnB1c2goc3RhdGUucmVzdWx0KTsKCiAgaWYgKHN0YXRlLnBvc2l0aW9uID09PSBzdGF0ZS5saW5lU3RhcnQgJiYgdGVzdERvY3VtZW50U2VwYXJhdG9yKHN0YXRlKSkgewoKICAgIGlmIChzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKSA9PT0gMHgyRS8qIC4gKi8pIHsKICAgICAgc3RhdGUucG9zaXRpb24gKz0gMzsKICAgICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpOwogICAgfQogICAgcmV0dXJuOwogIH0KCiAgaWYgKHN0YXRlLnBvc2l0aW9uIDwgKHN0YXRlLmxlbmd0aCAtIDEpKSB7CiAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZW5kIG9mIHRoZSBzdHJlYW0gb3IgYSBkb2N1bWVudCBzZXBhcmF0b3IgaXMgZXhwZWN0ZWQnKTsKICB9IGVsc2UgewogICAgcmV0dXJuOwogIH0KfQoKCmZ1bmN0aW9uIGxvYWREb2N1bWVudHMoaW5wdXQsIG9wdGlvbnMpIHsKICBpbnB1dCA9IFN0cmluZyhpbnB1dCk7CiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CgogIGlmIChpbnB1dC5sZW5ndGggIT09IDApIHsKICAgIGlmIChpbnB1dC5jaGFyQ29kZUF0KGlucHV0Lmxlbmd0aCAtIDEpICE9PSAweDBBLyogTEYgKi8gJiYKICAgICAgICBpbnB1dC5jaGFyQ29kZUF0KGlucHV0Lmxlbmd0aCAtIDEpICE9PSAweDBELyogQ1IgKi8pIHsKICAgICAgaW5wdXQgKz0gJ1xuJzsKICAgIH0KICAgIGlmIChpbnB1dC5jaGFyQ29kZUF0KDApID09PSAweEZFRkYpIHsKICAgICAgaW5wdXQgPSBpbnB1dC5zbGljZSgxKTsKICAgIH0KICB9CgogIHZhciBzdGF0ZSA9IG5ldyBTdGF0ZShpbnB1dCwgb3B0aW9ucyk7CiAgc3RhdGUuaW5wdXQgKz0gJ1wwJzsKCiAgd2hpbGUgKHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pID09PSAweDIwLyogU3BhY2UgKi8pIHsKICAgIHN0YXRlLmxpbmVJbmRlbnQgKz0gMTsKICAgIHN0YXRlLnBvc2l0aW9uICs9IDE7CiAgfQoKICB3aGlsZSAoc3RhdGUucG9zaXRpb24gPCAoc3RhdGUubGVuZ3RoIC0gMSkpIHsKICAgIHJlYWREb2N1bWVudChzdGF0ZSk7CiAgfQoKICByZXR1cm4gc3RhdGUuZG9jdW1lbnRzOwp9CgoKZnVuY3Rpb24gbG9hZEFsbChpbnB1dCwgaXRlcmF0b3IsIG9wdGlvbnMpIHsKICB2YXIgZG9jdW1lbnRzID0gbG9hZERvY3VtZW50cyhpbnB1dCwgb3B0aW9ucyksIGluZGV4LCBsZW5ndGg7CgogIGlmICh0eXBlb2YgaXRlcmF0b3IgIT09ICdmdW5jdGlvbicpIHsKICAgIHJldHVybiBkb2N1bWVudHM7CiAgfQoKICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gZG9jdW1lbnRzLmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHsKICAgIGl0ZXJhdG9yKGRvY3VtZW50c1tpbmRleF0pOwogIH0KfQoKCmZ1bmN0aW9uIGxvYWQoaW5wdXQsIG9wdGlvbnMpIHsKICB2YXIgZG9jdW1lbnRzID0gbG9hZERvY3VtZW50cyhpbnB1dCwgb3B0aW9ucyk7CgogIGlmIChkb2N1bWVudHMubGVuZ3RoID09PSAwKSB7CiAgICByZXR1cm4gdW5kZWZpbmVkOwogIH0gZWxzZSBpZiAoZG9jdW1lbnRzLmxlbmd0aCA9PT0gMSkgewogICAgcmV0dXJuIGRvY3VtZW50c1swXTsKICB9CiAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ2V4cGVjdGVkIGEgc2luZ2xlIGRvY3VtZW50IGluIHRoZSBzdHJlYW0sIGJ1dCBmb3VuZCBtb3JlJyk7Cn0KCgpmdW5jdGlvbiBzYWZlTG9hZEFsbChpbnB1dCwgb3V0cHV0LCBvcHRpb25zKSB7CiAgaWYgKHR5cGVvZiBvdXRwdXQgPT09ICdmdW5jdGlvbicpIHsKICAgIGxvYWRBbGwoaW5wdXQsIG91dHB1dCwgY29tbW9uLmV4dGVuZCh7IHNjaGVtYTogREVGQVVMVF9TQUZFX1NDSEVNQSB9LCBvcHRpb25zKSk7CiAgfSBlbHNlIHsKICAgIHJldHVybiBsb2FkQWxsKGlucHV0LCBjb21tb24uZXh0ZW5kKHsgc2NoZW1hOiBERUZBVUxUX1NBRkVfU0NIRU1BIH0sIG9wdGlvbnMpKTsKICB9Cn0KCgpmdW5jdGlvbiBzYWZlTG9hZChpbnB1dCwgb3B0aW9ucykgewogIHJldHVybiBsb2FkKGlucHV0LCBjb21tb24uZXh0ZW5kKHsgc2NoZW1hOiBERUZBVUxUX1NBRkVfU0NIRU1BIH0sIG9wdGlvbnMpKTsKfQoKCm1vZHVsZS5leHBvcnRzLmxvYWRBbGwgICAgID0gbG9hZEFsbDsKbW9kdWxlLmV4cG9ydHMubG9hZCAgICAgICAgPSBsb2FkOwptb2R1bGUuZXhwb3J0cy5zYWZlTG9hZEFsbCA9IHNhZmVMb2FkQWxsOwptb2R1bGUuZXhwb3J0cy5zYWZlTG9hZCAgICA9IHNhZmVMb2FkOwoKfSx7Ii4vY29tbW9uIjo1LCIuL2V4Y2VwdGlvbiI6NywiLi9tYXJrIjo5LCIuL3NjaGVtYS9kZWZhdWx0X2Z1bGwiOjEyLCIuL3NjaGVtYS9kZWZhdWx0X3NhZmUiOjEzfV0sOTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCgp2YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTsKCgpmdW5jdGlvbiBNYXJrKG5hbWUsIGJ1ZmZlciwgcG9zaXRpb24sIGxpbmUsIGNvbHVtbikgewogIHRoaXMubmFtZSAgICAgPSBuYW1lOwogIHRoaXMuYnVmZmVyICAgPSBidWZmZXI7CiAgdGhpcy5wb3NpdGlvbiA9IHBvc2l0aW9uOwogIHRoaXMubGluZSAgICAgPSBsaW5lOwogIHRoaXMuY29sdW1uICAgPSBjb2x1bW47Cn0KCgpNYXJrLnByb3RvdHlwZS5nZXRTbmlwcGV0ID0gZnVuY3Rpb24gZ2V0U25pcHBldChpbmRlbnQsIG1heExlbmd0aCkgewogIHZhciBoZWFkLCBzdGFydCwgdGFpbCwgZW5kLCBzbmlwcGV0OwoKICBpZiAoIXRoaXMuYnVmZmVyKSByZXR1cm4gbnVsbDsKCiAgaW5kZW50ID0gaW5kZW50IHx8IDQ7CiAgbWF4TGVuZ3RoID0gbWF4TGVuZ3RoIHx8IDc1OwoKICBoZWFkID0gJyc7CiAgc3RhcnQgPSB0aGlzLnBvc2l0aW9uOwoKICB3aGlsZSAoc3RhcnQgPiAwICYmICdceDAwXHJcblx4ODVcdTIwMjhcdTIwMjknLmluZGV4T2YodGhpcy5idWZmZXIuY2hhckF0KHN0YXJ0IC0gMSkpID09PSAtMSkgewogICAgc3RhcnQgLT0gMTsKICAgIGlmICh0aGlzLnBvc2l0aW9uIC0gc3RhcnQgPiAobWF4TGVuZ3RoIC8gMiAtIDEpKSB7CiAgICAgIGhlYWQgPSAnIC4uLiAnOwogICAgICBzdGFydCArPSA1OwogICAgICBicmVhazsKICAgIH0KICB9CgogIHRhaWwgPSAnJzsKICBlbmQgPSB0aGlzLnBvc2l0aW9uOwoKICB3aGlsZSAoZW5kIDwgdGhpcy5idWZmZXIubGVuZ3RoICYmICdceDAwXHJcblx4ODVcdTIwMjhcdTIwMjknLmluZGV4T2YodGhpcy5idWZmZXIuY2hhckF0KGVuZCkpID09PSAtMSkgewogICAgZW5kICs9IDE7CiAgICBpZiAoZW5kIC0gdGhpcy5wb3NpdGlvbiA+IChtYXhMZW5ndGggLyAyIC0gMSkpIHsKICAgICAgdGFpbCA9ICcgLi4uICc7CiAgICAgIGVuZCAtPSA1OwogICAgICBicmVhazsKICAgIH0KICB9CgogIHNuaXBwZXQgPSB0aGlzLmJ1ZmZlci5zbGljZShzdGFydCwgZW5kKTsKCiAgcmV0dXJuIGNvbW1vbi5yZXBlYXQoJyAnLCBpbmRlbnQpICsgaGVhZCArIHNuaXBwZXQgKyB0YWlsICsgJ1xuJyArCiAgICAgICAgIGNvbW1vbi5yZXBlYXQoJyAnLCBpbmRlbnQgKyB0aGlzLnBvc2l0aW9uIC0gc3RhcnQgKyBoZWFkLmxlbmd0aCkgKyAnXic7Cn07CgoKTWFyay5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyhjb21wYWN0KSB7CiAgdmFyIHNuaXBwZXQsIHdoZXJlID0gJyc7CgogIGlmICh0aGlzLm5hbWUpIHsKICAgIHdoZXJlICs9ICdpbiAiJyArIHRoaXMubmFtZSArICciICc7CiAgfQoKICB3aGVyZSArPSAnYXQgbGluZSAnICsgKHRoaXMubGluZSArIDEpICsgJywgY29sdW1uICcgKyAodGhpcy5jb2x1bW4gKyAxKTsKCiAgaWYgKCFjb21wYWN0KSB7CiAgICBzbmlwcGV0ID0gdGhpcy5nZXRTbmlwcGV0KCk7CgogICAgaWYgKHNuaXBwZXQpIHsKICAgICAgd2hlcmUgKz0gJzpcbicgKyBzbmlwcGV0OwogICAgfQogIH0KCiAgcmV0dXJuIHdoZXJlOwp9OwoKCm1vZHVsZS5leHBvcnRzID0gTWFyazsKCn0seyIuL2NvbW1vbiI6NX1dLDEwOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKdmFyIGNvbW1vbiAgICAgICAgPSByZXF1aXJlKCcuL2NvbW1vbicpOwp2YXIgWUFNTEV4Y2VwdGlvbiA9IHJlcXVpcmUoJy4vZXhjZXB0aW9uJyk7CnZhciBUeXBlICAgICAgICAgID0gcmVxdWlyZSgnLi90eXBlJyk7CgoKZnVuY3Rpb24gY29tcGlsZUxpc3Qoc2NoZW1hLCBuYW1lLCByZXN1bHQpIHsKICB2YXIgZXhjbHVkZSA9IFtdOwoKICBzY2hlbWEuaW5jbHVkZS5mb3JFYWNoKGZ1bmN0aW9uIChpbmNsdWRlZFNjaGVtYSkgewogICAgcmVzdWx0ID0gY29tcGlsZUxpc3QoaW5jbHVkZWRTY2hlbWEsIG5hbWUsIHJlc3VsdCk7CiAgfSk7CgogIHNjaGVtYVtuYW1lXS5mb3JFYWNoKGZ1bmN0aW9uIChjdXJyZW50VHlwZSkgewogICAgcmVzdWx0LmZvckVhY2goZnVuY3Rpb24gKHByZXZpb3VzVHlwZSwgcHJldmlvdXNJbmRleCkgewogICAgICBpZiAocHJldmlvdXNUeXBlLnRhZyA9PT0gY3VycmVudFR5cGUudGFnICYmIHByZXZpb3VzVHlwZS5raW5kID09PSBjdXJyZW50VHlwZS5raW5kKSB7CiAgICAgICAgZXhjbHVkZS5wdXNoKHByZXZpb3VzSW5kZXgpOwogICAgICB9CiAgICB9KTsKCiAgICByZXN1bHQucHVzaChjdXJyZW50VHlwZSk7CiAgfSk7CgogIHJldHVybiByZXN1bHQuZmlsdGVyKGZ1bmN0aW9uICh0eXBlLCBpbmRleCkgewogICAgcmV0dXJuIGV4Y2x1ZGUuaW5kZXhPZihpbmRleCkgPT09IC0xOwogIH0pOwp9CgoKZnVuY3Rpb24gY29tcGlsZU1hcCgvKiBsaXN0cy4uLiAqLykgewogIHZhciByZXN1bHQgPSB7CiAgICAgICAgc2NhbGFyOiB7fSwKICAgICAgICBzZXF1ZW5jZToge30sCiAgICAgICAgbWFwcGluZzoge30sCiAgICAgICAgZmFsbGJhY2s6IHt9CiAgICAgIH0sIGluZGV4LCBsZW5ndGg7CgogIGZ1bmN0aW9uIGNvbGxlY3RUeXBlKHR5cGUpIHsKICAgIHJlc3VsdFt0eXBlLmtpbmRdW3R5cGUudGFnXSA9IHJlc3VsdFsnZmFsbGJhY2snXVt0eXBlLnRhZ10gPSB0eXBlOwogIH0KCiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7CiAgICBhcmd1bWVudHNbaW5kZXhdLmZvckVhY2goY29sbGVjdFR5cGUpOwogIH0KICByZXR1cm4gcmVzdWx0Owp9CgoKZnVuY3Rpb24gU2NoZW1hKGRlZmluaXRpb24pIHsKICB0aGlzLmluY2x1ZGUgID0gZGVmaW5pdGlvbi5pbmNsdWRlICB8fCBbXTsKICB0aGlzLmltcGxpY2l0ID0gZGVmaW5pdGlvbi5pbXBsaWNpdCB8fCBbXTsKICB0aGlzLmV4cGxpY2l0ID0gZGVmaW5pdGlvbi5leHBsaWNpdCB8fCBbXTsKCiAgdGhpcy5pbXBsaWNpdC5mb3JFYWNoKGZ1bmN0aW9uICh0eXBlKSB7CiAgICBpZiAodHlwZS5sb2FkS2luZCAmJiB0eXBlLmxvYWRLaW5kICE9PSAnc2NhbGFyJykgewogICAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignVGhlcmUgaXMgYSBub24tc2NhbGFyIHR5cGUgaW4gdGhlIGltcGxpY2l0IGxpc3Qgb2YgYSBzY2hlbWEuIEltcGxpY2l0IHJlc29sdmluZyBvZiBzdWNoIHR5cGVzIGlzIG5vdCBzdXBwb3J0ZWQuJyk7CiAgICB9CiAgfSk7CgogIHRoaXMuY29tcGlsZWRJbXBsaWNpdCA9IGNvbXBpbGVMaXN0KHRoaXMsICdpbXBsaWNpdCcsIFtdKTsKICB0aGlzLmNvbXBpbGVkRXhwbGljaXQgPSBjb21waWxlTGlzdCh0aGlzLCAnZXhwbGljaXQnLCBbXSk7CiAgdGhpcy5jb21waWxlZFR5cGVNYXAgID0gY29tcGlsZU1hcCh0aGlzLmNvbXBpbGVkSW1wbGljaXQsIHRoaXMuY29tcGlsZWRFeHBsaWNpdCk7Cn0KCgpTY2hlbWEuREVGQVVMVCA9IG51bGw7CgoKU2NoZW1hLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZVNjaGVtYSgpIHsKICB2YXIgc2NoZW1hcywgdHlwZXM7CgogIHN3aXRjaCAoYXJndW1lbnRzLmxlbmd0aCkgewogICAgY2FzZSAxOgogICAgICBzY2hlbWFzID0gU2NoZW1hLkRFRkFVTFQ7CiAgICAgIHR5cGVzID0gYXJndW1lbnRzWzBdOwogICAgICBicmVhazsKCiAgICBjYXNlIDI6CiAgICAgIHNjaGVtYXMgPSBhcmd1bWVudHNbMF07CiAgICAgIHR5cGVzID0gYXJndW1lbnRzWzFdOwogICAgICBicmVhazsKCiAgICBkZWZhdWx0OgogICAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignV3JvbmcgbnVtYmVyIG9mIGFyZ3VtZW50cyBmb3IgU2NoZW1hLmNyZWF0ZSBmdW5jdGlvbicpOwogIH0KCiAgc2NoZW1hcyA9IGNvbW1vbi50b0FycmF5KHNjaGVtYXMpOwogIHR5cGVzID0gY29tbW9uLnRvQXJyYXkodHlwZXMpOwoKICBpZiAoIXNjaGVtYXMuZXZlcnkoZnVuY3Rpb24gKHNjaGVtYSkgeyByZXR1cm4gc2NoZW1hIGluc3RhbmNlb2YgU2NoZW1hOyB9KSkgewogICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ1NwZWNpZmllZCBsaXN0IG9mIHN1cGVyIHNjaGVtYXMgKG9yIGEgc2luZ2xlIFNjaGVtYSBvYmplY3QpIGNvbnRhaW5zIGEgbm9uLVNjaGVtYSBvYmplY3QuJyk7CiAgfQoKICBpZiAoIXR5cGVzLmV2ZXJ5KGZ1bmN0aW9uICh0eXBlKSB7IHJldHVybiB0eXBlIGluc3RhbmNlb2YgVHlwZTsgfSkpIHsKICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdTcGVjaWZpZWQgbGlzdCBvZiBZQU1MIHR5cGVzIChvciBhIHNpbmdsZSBUeXBlIG9iamVjdCkgY29udGFpbnMgYSBub24tVHlwZSBvYmplY3QuJyk7CiAgfQoKICByZXR1cm4gbmV3IFNjaGVtYSh7CiAgICBpbmNsdWRlOiBzY2hlbWFzLAogICAgZXhwbGljaXQ6IHR5cGVzCiAgfSk7Cn07CgoKbW9kdWxlLmV4cG9ydHMgPSBTY2hlbWE7Cgp9LHsiLi9jb21tb24iOjUsIi4vZXhjZXB0aW9uIjo3LCIuL3R5cGUiOjE2fV0sMTE6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewoKCid1c2Ugc3RyaWN0JzsKCgp2YXIgU2NoZW1hID0gcmVxdWlyZSgnLi4vc2NoZW1hJyk7CgoKbW9kdWxlLmV4cG9ydHMgPSBuZXcgU2NoZW1hKHsKICBpbmNsdWRlOiBbCiAgICByZXF1aXJlKCcuL2pzb24nKQogIF0KfSk7Cgp9LHsiLi4vc2NoZW1hIjoxMCwiLi9qc29uIjoxNX1dLDEyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKCgondXNlIHN0cmljdCc7CgoKdmFyIFNjaGVtYSA9IHJlcXVpcmUoJy4uL3NjaGVtYScpOwoKCm1vZHVsZS5leHBvcnRzID0gU2NoZW1hLkRFRkFVTFQgPSBuZXcgU2NoZW1hKHsKICBpbmNsdWRlOiBbCiAgICByZXF1aXJlKCcuL2RlZmF1bHRfc2FmZScpCiAgXSwKICBleHBsaWNpdDogWwogICAgcmVxdWlyZSgnLi4vdHlwZS9qcy91bmRlZmluZWQnKSwKICAgIHJlcXVpcmUoJy4uL3R5cGUvanMvcmVnZXhwJyksCiAgICByZXF1aXJlKCcuLi90eXBlL2pzL2Z1bmN0aW9uJykKICBdCn0pOwoKfSx7Ii4uL3NjaGVtYSI6MTAsIi4uL3R5cGUvanMvZnVuY3Rpb24iOjIxLCIuLi90eXBlL2pzL3JlZ2V4cCI6MjIsIi4uL3R5cGUvanMvdW5kZWZpbmVkIjoyMywiLi9kZWZhdWx0X3NhZmUiOjEzfV0sMTM6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewoKCid1c2Ugc3RyaWN0JzsKCgp2YXIgU2NoZW1hID0gcmVxdWlyZSgnLi4vc2NoZW1hJyk7CgoKbW9kdWxlLmV4cG9ydHMgPSBuZXcgU2NoZW1hKHsKICBpbmNsdWRlOiBbCiAgICByZXF1aXJlKCcuL2NvcmUnKQogIF0sCiAgaW1wbGljaXQ6IFsKICAgIHJlcXVpcmUoJy4uL3R5cGUvdGltZXN0YW1wJyksCiAgICByZXF1aXJlKCcuLi90eXBlL21lcmdlJykKICBdLAogIGV4cGxpY2l0OiBbCiAgICByZXF1aXJlKCcuLi90eXBlL2JpbmFyeScpLAogICAgcmVxdWlyZSgnLi4vdHlwZS9vbWFwJyksCiAgICByZXF1aXJlKCcuLi90eXBlL3BhaXJzJyksCiAgICByZXF1aXJlKCcuLi90eXBlL3NldCcpCiAgXQp9KTsKCn0seyIuLi9zY2hlbWEiOjEwLCIuLi90eXBlL2JpbmFyeSI6MTcsIi4uL3R5cGUvbWVyZ2UiOjI1LCIuLi90eXBlL29tYXAiOjI3LCIuLi90eXBlL3BhaXJzIjoyOCwiLi4vdHlwZS9zZXQiOjMwLCIuLi90eXBlL3RpbWVzdGFtcCI6MzIsIi4vY29yZSI6MTF9XSwxNDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7CgoKJ3VzZSBzdHJpY3QnOwoKCnZhciBTY2hlbWEgPSByZXF1aXJlKCcuLi9zY2hlbWEnKTsKCgptb2R1bGUuZXhwb3J0cyA9IG5ldyBTY2hlbWEoewogIGV4cGxpY2l0OiBbCiAgICByZXF1aXJlKCcuLi90eXBlL3N0cicpLAogICAgcmVxdWlyZSgnLi4vdHlwZS9zZXEnKSwKICAgIHJlcXVpcmUoJy4uL3R5cGUvbWFwJykKICBdCn0pOwoKfSx7Ii4uL3NjaGVtYSI6MTAsIi4uL3R5cGUvbWFwIjoyNCwiLi4vdHlwZS9zZXEiOjI5LCIuLi90eXBlL3N0ciI6MzF9XSwxNTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7CgoKJ3VzZSBzdHJpY3QnOwoKCnZhciBTY2hlbWEgPSByZXF1aXJlKCcuLi9zY2hlbWEnKTsKCgptb2R1bGUuZXhwb3J0cyA9IG5ldyBTY2hlbWEoewogIGluY2x1ZGU6IFsKICAgIHJlcXVpcmUoJy4vZmFpbHNhZmUnKQogIF0sCiAgaW1wbGljaXQ6IFsKICAgIHJlcXVpcmUoJy4uL3R5cGUvbnVsbCcpLAogICAgcmVxdWlyZSgnLi4vdHlwZS9ib29sJyksCiAgICByZXF1aXJlKCcuLi90eXBlL2ludCcpLAogICAgcmVxdWlyZSgnLi4vdHlwZS9mbG9hdCcpCiAgXQp9KTsKCn0seyIuLi9zY2hlbWEiOjEwLCIuLi90eXBlL2Jvb2wiOjE4LCIuLi90eXBlL2Zsb2F0IjoxOSwiLi4vdHlwZS9pbnQiOjIwLCIuLi90eXBlL251bGwiOjI2LCIuL2ZhaWxzYWZlIjoxNH1dLDE2OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKdmFyIFlBTUxFeGNlcHRpb24gPSByZXF1aXJlKCcuL2V4Y2VwdGlvbicpOwoKdmFyIFRZUEVfQ09OU1RSVUNUT1JfT1BUSU9OUyA9IFsKICAna2luZCcsCiAgJ3Jlc29sdmUnLAogICdjb25zdHJ1Y3QnLAogICdpbnN0YW5jZU9mJywKICAncHJlZGljYXRlJywKICAncmVwcmVzZW50JywKICAnZGVmYXVsdFN0eWxlJywKICAnc3R5bGVBbGlhc2VzJwpdOwoKdmFyIFlBTUxfTk9ERV9LSU5EUyA9IFsKICAnc2NhbGFyJywKICAnc2VxdWVuY2UnLAogICdtYXBwaW5nJwpdOwoKZnVuY3Rpb24gY29tcGlsZVN0eWxlQWxpYXNlcyhtYXApIHsKICB2YXIgcmVzdWx0ID0ge307CgogIGlmIChtYXAgIT09IG51bGwpIHsKICAgIE9iamVjdC5rZXlzKG1hcCkuZm9yRWFjaChmdW5jdGlvbiAoc3R5bGUpIHsKICAgICAgbWFwW3N0eWxlXS5mb3JFYWNoKGZ1bmN0aW9uIChhbGlhcykgewogICAgICAgIHJlc3VsdFtTdHJpbmcoYWxpYXMpXSA9IHN0eWxlOwogICAgICB9KTsKICAgIH0pOwogIH0KCiAgcmV0dXJuIHJlc3VsdDsKfQoKZnVuY3Rpb24gVHlwZSh0YWcsIG9wdGlvbnMpIHsKICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKCiAgT2JqZWN0LmtleXMob3B0aW9ucykuZm9yRWFjaChmdW5jdGlvbiAobmFtZSkgewogICAgaWYgKFRZUEVfQ09OU1RSVUNUT1JfT1BUSU9OUy5pbmRleE9mKG5hbWUpID09PSAtMSkgewogICAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignVW5rbm93biBvcHRpb24gIicgKyBuYW1lICsgJyIgaXMgbWV0IGluIGRlZmluaXRpb24gb2YgIicgKyB0YWcgKyAnIiBZQU1MIHR5cGUuJyk7CiAgICB9CiAgfSk7CiAgdGhpcy50YWcgICAgICAgICAgPSB0YWc7CiAgdGhpcy5raW5kICAgICAgICAgPSBvcHRpb25zWydraW5kJ10gICAgICAgICB8fCBudWxsOwogIHRoaXMucmVzb2x2ZSAgICAgID0gb3B0aW9uc1sncmVzb2x2ZSddICAgICAgfHwgZnVuY3Rpb24gKCkgeyByZXR1cm4gdHJ1ZTsgfTsKICB0aGlzLmNvbnN0cnVjdCAgICA9IG9wdGlvbnNbJ2NvbnN0cnVjdCddICAgIHx8IGZ1bmN0aW9uIChkYXRhKSB7IHJldHVybiBkYXRhOyB9OwogIHRoaXMuaW5zdGFuY2VPZiAgID0gb3B0aW9uc1snaW5zdGFuY2VPZiddICAgfHwgbnVsbDsKICB0aGlzLnByZWRpY2F0ZSAgICA9IG9wdGlvbnNbJ3ByZWRpY2F0ZSddICAgIHx8IG51bGw7CiAgdGhpcy5yZXByZXNlbnQgICAgPSBvcHRpb25zWydyZXByZXNlbnQnXSAgICB8fCBudWxsOwogIHRoaXMuZGVmYXVsdFN0eWxlID0gb3B0aW9uc1snZGVmYXVsdFN0eWxlJ10gfHwgbnVsbDsKICB0aGlzLnN0eWxlQWxpYXNlcyA9IGNvbXBpbGVTdHlsZUFsaWFzZXMob3B0aW9uc1snc3R5bGVBbGlhc2VzJ10gfHwgbnVsbCk7CgogIGlmIChZQU1MX05PREVfS0lORFMuaW5kZXhPZih0aGlzLmtpbmQpID09PSAtMSkgewogICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ1Vua25vd24ga2luZCAiJyArIHRoaXMua2luZCArICciIGlzIHNwZWNpZmllZCBmb3IgIicgKyB0YWcgKyAnIiBZQU1MIHR5cGUuJyk7CiAgfQp9Cgptb2R1bGUuZXhwb3J0cyA9IFR5cGU7Cgp9LHsiLi9leGNlcHRpb24iOjd9XSwxNzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCnZhciBOb2RlQnVmZmVyOwoKdHJ5IHsKICB2YXIgX3JlcXVpcmUgPSByZXF1aXJlOwogIE5vZGVCdWZmZXIgPSBfcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyOwp9IGNhdGNoIChfXykge30KCnZhciBUeXBlICAgICAgID0gcmVxdWlyZSgnLi4vdHlwZScpOwp2YXIgQkFTRTY0X01BUCA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvPVxuXHInOwoKCmZ1bmN0aW9uIHJlc29sdmVZYW1sQmluYXJ5KGRhdGEpIHsKICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIGZhbHNlOwoKICB2YXIgY29kZSwgaWR4LCBiaXRsZW4gPSAwLCBtYXggPSBkYXRhLmxlbmd0aCwgbWFwID0gQkFTRTY0X01BUDsKICBmb3IgKGlkeCA9IDA7IGlkeCA8IG1heDsgaWR4KyspIHsKICAgIGNvZGUgPSBtYXAuaW5kZXhPZihkYXRhLmNoYXJBdChpZHgpKTsKICAgIGlmIChjb2RlID4gNjQpIGNvbnRpbnVlOwogICAgaWYgKGNvZGUgPCAwKSByZXR1cm4gZmFsc2U7CgogICAgYml0bGVuICs9IDY7CiAgfQogIHJldHVybiAoYml0bGVuICUgOCkgPT09IDA7Cn0KCmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxCaW5hcnkoZGF0YSkgewogIHZhciBpZHgsIHRhaWxiaXRzLAogICAgICBpbnB1dCA9IGRhdGEucmVwbGFjZSgvW1xyXG49XS9nLCAnJyksIC8vIHJlbW92ZSBDUi9MRiAmIHBhZGRpbmcgdG8gc2ltcGxpZnkgc2NhbgogICAgICBtYXggPSBpbnB1dC5sZW5ndGgsCiAgICAgIG1hcCA9IEJBU0U2NF9NQVAsCiAgICAgIGJpdHMgPSAwLAogICAgICByZXN1bHQgPSBbXTsKCiAgZm9yIChpZHggPSAwOyBpZHggPCBtYXg7IGlkeCsrKSB7CiAgICBpZiAoKGlkeCAlIDQgPT09IDApICYmIGlkeCkgewogICAgICByZXN1bHQucHVzaCgoYml0cyA+PiAxNikgJiAweEZGKTsKICAgICAgcmVzdWx0LnB1c2goKGJpdHMgPj4gOCkgJiAweEZGKTsKICAgICAgcmVzdWx0LnB1c2goYml0cyAmIDB4RkYpOwogICAgfQoKICAgIGJpdHMgPSAoYml0cyA8PCA2KSB8IG1hcC5pbmRleE9mKGlucHV0LmNoYXJBdChpZHgpKTsKICB9CgogIHRhaWxiaXRzID0gKG1heCAlIDQpICogNjsKCiAgaWYgKHRhaWxiaXRzID09PSAwKSB7CiAgICByZXN1bHQucHVzaCgoYml0cyA+PiAxNikgJiAweEZGKTsKICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDgpICYgMHhGRik7CiAgICByZXN1bHQucHVzaChiaXRzICYgMHhGRik7CiAgfSBlbHNlIGlmICh0YWlsYml0cyA9PT0gMTgpIHsKICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDEwKSAmIDB4RkYpOwogICAgcmVzdWx0LnB1c2goKGJpdHMgPj4gMikgJiAweEZGKTsKICB9IGVsc2UgaWYgKHRhaWxiaXRzID09PSAxMikgewogICAgcmVzdWx0LnB1c2goKGJpdHMgPj4gNCkgJiAweEZGKTsKICB9CiAgaWYgKE5vZGVCdWZmZXIpIHsKICAgIHJldHVybiBOb2RlQnVmZmVyLmZyb20gPyBOb2RlQnVmZmVyLmZyb20ocmVzdWx0KSA6IG5ldyBOb2RlQnVmZmVyKHJlc3VsdCk7CiAgfQoKICByZXR1cm4gcmVzdWx0Owp9CgpmdW5jdGlvbiByZXByZXNlbnRZYW1sQmluYXJ5KG9iamVjdCAvKiwgc3R5bGUqLykgewogIHZhciByZXN1bHQgPSAnJywgYml0cyA9IDAsIGlkeCwgdGFpbCwKICAgICAgbWF4ID0gb2JqZWN0Lmxlbmd0aCwKICAgICAgbWFwID0gQkFTRTY0X01BUDsKCiAgZm9yIChpZHggPSAwOyBpZHggPCBtYXg7IGlkeCsrKSB7CiAgICBpZiAoKGlkeCAlIDMgPT09IDApICYmIGlkeCkgewogICAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDE4KSAmIDB4M0ZdOwogICAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDEyKSAmIDB4M0ZdOwogICAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDYpICYgMHgzRl07CiAgICAgIHJlc3VsdCArPSBtYXBbYml0cyAmIDB4M0ZdOwogICAgfQoKICAgIGJpdHMgPSAoYml0cyA8PCA4KSArIG9iamVjdFtpZHhdOwogIH0KCiAgdGFpbCA9IG1heCAlIDM7CgogIGlmICh0YWlsID09PSAwKSB7CiAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDE4KSAmIDB4M0ZdOwogICAgcmVzdWx0ICs9IG1hcFsoYml0cyA+PiAxMikgJiAweDNGXTsKICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gNikgJiAweDNGXTsKICAgIHJlc3VsdCArPSBtYXBbYml0cyAmIDB4M0ZdOwogIH0gZWxzZSBpZiAodGFpbCA9PT0gMikgewogICAgcmVzdWx0ICs9IG1hcFsoYml0cyA+PiAxMCkgJiAweDNGXTsKICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gNCkgJiAweDNGXTsKICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPDwgMikgJiAweDNGXTsKICAgIHJlc3VsdCArPSBtYXBbNjRdOwogIH0gZWxzZSBpZiAodGFpbCA9PT0gMSkgewogICAgcmVzdWx0ICs9IG1hcFsoYml0cyA+PiAyKSAmIDB4M0ZdOwogICAgcmVzdWx0ICs9IG1hcFsoYml0cyA8PCA0KSAmIDB4M0ZdOwogICAgcmVzdWx0ICs9IG1hcFs2NF07CiAgICByZXN1bHQgKz0gbWFwWzY0XTsKICB9CgogIHJldHVybiByZXN1bHQ7Cn0KCmZ1bmN0aW9uIGlzQmluYXJ5KG9iamVjdCkgewogIHJldHVybiBOb2RlQnVmZmVyICYmIE5vZGVCdWZmZXIuaXNCdWZmZXIob2JqZWN0KTsKfQoKbW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6YmluYXJ5JywgewogIGtpbmQ6ICdzY2FsYXInLAogIHJlc29sdmU6IHJlc29sdmVZYW1sQmluYXJ5LAogIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbEJpbmFyeSwKICBwcmVkaWNhdGU6IGlzQmluYXJ5LAogIHJlcHJlc2VudDogcmVwcmVzZW50WWFtbEJpbmFyeQp9KTsKCn0seyIuLi90eXBlIjoxNn1dLDE4OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKdmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7CgpmdW5jdGlvbiByZXNvbHZlWWFtbEJvb2xlYW4oZGF0YSkgewogIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gZmFsc2U7CgogIHZhciBtYXggPSBkYXRhLmxlbmd0aDsKCiAgcmV0dXJuIChtYXggPT09IDQgJiYgKGRhdGEgPT09ICd0cnVlJyB8fCBkYXRhID09PSAnVHJ1ZScgfHwgZGF0YSA9PT0gJ1RSVUUnKSkgfHwKICAgICAgICAgKG1heCA9PT0gNSAmJiAoZGF0YSA9PT0gJ2ZhbHNlJyB8fCBkYXRhID09PSAnRmFsc2UnIHx8IGRhdGEgPT09ICdGQUxTRScpKTsKfQoKZnVuY3Rpb24gY29uc3RydWN0WWFtbEJvb2xlYW4oZGF0YSkgewogIHJldHVybiBkYXRhID09PSAndHJ1ZScgfHwKICAgICAgICAgZGF0YSA9PT0gJ1RydWUnIHx8CiAgICAgICAgIGRhdGEgPT09ICdUUlVFJzsKfQoKZnVuY3Rpb24gaXNCb29sZWFuKG9iamVjdCkgewogIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqZWN0KSA9PT0gJ1tvYmplY3QgQm9vbGVhbl0nOwp9Cgptb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpib29sJywgewogIGtpbmQ6ICdzY2FsYXInLAogIHJlc29sdmU6IHJlc29sdmVZYW1sQm9vbGVhbiwKICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdFlhbWxCb29sZWFuLAogIHByZWRpY2F0ZTogaXNCb29sZWFuLAogIHJlcHJlc2VudDogewogICAgbG93ZXJjYXNlOiBmdW5jdGlvbiAob2JqZWN0KSB7IHJldHVybiBvYmplY3QgPyAndHJ1ZScgOiAnZmFsc2UnOyB9LAogICAgdXBwZXJjYXNlOiBmdW5jdGlvbiAob2JqZWN0KSB7IHJldHVybiBvYmplY3QgPyAnVFJVRScgOiAnRkFMU0UnOyB9LAogICAgY2FtZWxjYXNlOiBmdW5jdGlvbiAob2JqZWN0KSB7IHJldHVybiBvYmplY3QgPyAnVHJ1ZScgOiAnRmFsc2UnOyB9CiAgfSwKICBkZWZhdWx0U3R5bGU6ICdsb3dlcmNhc2UnCn0pOwoKfSx7Ii4uL3R5cGUiOjE2fV0sMTk6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7Cgp2YXIgY29tbW9uID0gcmVxdWlyZSgnLi4vY29tbW9uJyk7CnZhciBUeXBlICAgPSByZXF1aXJlKCcuLi90eXBlJyk7Cgp2YXIgWUFNTF9GTE9BVF9QQVRURVJOID0gbmV3IFJlZ0V4cCgKICAnXig/OlstK10/KD86MHxbMS05XVswLTlfXSopKD86XFwuWzAtOV9dKik/KD86W2VFXVstK10/WzAtOV0rKT8nICsKICAnfFxcLlswLTlfXSsoPzpbZUVdWy0rXT9bMC05XSspPycgKwogICd8Wy0rXT9bMC05XVswLTlfXSooPzo6WzAtNV0/WzAtOV0pK1xcLlswLTlfXSonICsKICAnfFstK10/XFwuKD86aW5mfEluZnxJTkYpJyArCiAgJ3xcXC4oPzpuYW58TmFOfE5BTikpJCcpOwoKZnVuY3Rpb24gcmVzb2x2ZVlhbWxGbG9hdChkYXRhKSB7CiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiBmYWxzZTsKCiAgaWYgKCFZQU1MX0ZMT0FUX1BBVFRFUk4udGVzdChkYXRhKSB8fAogICAgICBkYXRhW2RhdGEubGVuZ3RoIC0gMV0gPT09ICdfJykgewogICAgcmV0dXJuIGZhbHNlOwogIH0KCiAgcmV0dXJuIHRydWU7Cn0KCmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxGbG9hdChkYXRhKSB7CiAgdmFyIHZhbHVlLCBzaWduLCBiYXNlLCBkaWdpdHM7CgogIHZhbHVlICA9IGRhdGEucmVwbGFjZSgvXy9nLCAnJykudG9Mb3dlckNhc2UoKTsKICBzaWduICAgPSB2YWx1ZVswXSA9PT0gJy0nID8gLTEgOiAxOwogIGRpZ2l0cyA9IFtdOwoKICBpZiAoJystJy5pbmRleE9mKHZhbHVlWzBdKSA+PSAwKSB7CiAgICB2YWx1ZSA9IHZhbHVlLnNsaWNlKDEpOwogIH0KCiAgaWYgKHZhbHVlID09PSAnLmluZicpIHsKICAgIHJldHVybiAoc2lnbiA9PT0gMSkgPyBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkgOiBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFk7CgogIH0gZWxzZSBpZiAodmFsdWUgPT09ICcubmFuJykgewogICAgcmV0dXJuIE5hTjsKCiAgfSBlbHNlIGlmICh2YWx1ZS5pbmRleE9mKCc6JykgPj0gMCkgewogICAgdmFsdWUuc3BsaXQoJzonKS5mb3JFYWNoKGZ1bmN0aW9uICh2KSB7CiAgICAgIGRpZ2l0cy51bnNoaWZ0KHBhcnNlRmxvYXQodiwgMTApKTsKICAgIH0pOwoKICAgIHZhbHVlID0gMC4wOwogICAgYmFzZSA9IDE7CgogICAgZGlnaXRzLmZvckVhY2goZnVuY3Rpb24gKGQpIHsKICAgICAgdmFsdWUgKz0gZCAqIGJhc2U7CiAgICAgIGJhc2UgKj0gNjA7CiAgICB9KTsKCiAgICByZXR1cm4gc2lnbiAqIHZhbHVlOwoKICB9CiAgcmV0dXJuIHNpZ24gKiBwYXJzZUZsb2F0KHZhbHVlLCAxMCk7Cn0KCgp2YXIgU0NJRU5USUZJQ19XSVRIT1VUX0RPVCA9IC9eWy0rXT9bMC05XStlLzsKCmZ1bmN0aW9uIHJlcHJlc2VudFlhbWxGbG9hdChvYmplY3QsIHN0eWxlKSB7CiAgdmFyIHJlczsKCiAgaWYgKGlzTmFOKG9iamVjdCkpIHsKICAgIHN3aXRjaCAoc3R5bGUpIHsKICAgICAgY2FzZSAnbG93ZXJjYXNlJzogcmV0dXJuICcubmFuJzsKICAgICAgY2FzZSAndXBwZXJjYXNlJzogcmV0dXJuICcuTkFOJzsKICAgICAgY2FzZSAnY2FtZWxjYXNlJzogcmV0dXJuICcuTmFOJzsKICAgIH0KICB9IGVsc2UgaWYgKE51bWJlci5QT1NJVElWRV9JTkZJTklUWSA9PT0gb2JqZWN0KSB7CiAgICBzd2l0Y2ggKHN0eWxlKSB7CiAgICAgIGNhc2UgJ2xvd2VyY2FzZSc6IHJldHVybiAnLmluZic7CiAgICAgIGNhc2UgJ3VwcGVyY2FzZSc6IHJldHVybiAnLklORic7CiAgICAgIGNhc2UgJ2NhbWVsY2FzZSc6IHJldHVybiAnLkluZic7CiAgICB9CiAgfSBlbHNlIGlmIChOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFkgPT09IG9iamVjdCkgewogICAgc3dpdGNoIChzdHlsZSkgewogICAgICBjYXNlICdsb3dlcmNhc2UnOiByZXR1cm4gJy0uaW5mJzsKICAgICAgY2FzZSAndXBwZXJjYXNlJzogcmV0dXJuICctLklORic7CiAgICAgIGNhc2UgJ2NhbWVsY2FzZSc6IHJldHVybiAnLS5JbmYnOwogICAgfQogIH0gZWxzZSBpZiAoY29tbW9uLmlzTmVnYXRpdmVaZXJvKG9iamVjdCkpIHsKICAgIHJldHVybiAnLTAuMCc7CiAgfQoKICByZXMgPSBvYmplY3QudG9TdHJpbmcoMTApOwoKICByZXR1cm4gU0NJRU5USUZJQ19XSVRIT1VUX0RPVC50ZXN0KHJlcykgPyByZXMucmVwbGFjZSgnZScsICcuZScpIDogcmVzOwp9CgpmdW5jdGlvbiBpc0Zsb2F0KG9iamVjdCkgewogIHJldHVybiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iamVjdCkgPT09ICdbb2JqZWN0IE51bWJlcl0nKSAmJgogICAgICAgICAob2JqZWN0ICUgMSAhPT0gMCB8fCBjb21tb24uaXNOZWdhdGl2ZVplcm8ob2JqZWN0KSk7Cn0KCm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmZsb2F0JywgewogIGtpbmQ6ICdzY2FsYXInLAogIHJlc29sdmU6IHJlc29sdmVZYW1sRmxvYXQsCiAgY29uc3RydWN0OiBjb25zdHJ1Y3RZYW1sRmxvYXQsCiAgcHJlZGljYXRlOiBpc0Zsb2F0LAogIHJlcHJlc2VudDogcmVwcmVzZW50WWFtbEZsb2F0LAogIGRlZmF1bHRTdHlsZTogJ2xvd2VyY2FzZScKfSk7Cgp9LHsiLi4vY29tbW9uIjo1LCIuLi90eXBlIjoxNn1dLDIwOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKdmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4uL2NvbW1vbicpOwp2YXIgVHlwZSAgID0gcmVxdWlyZSgnLi4vdHlwZScpOwoKZnVuY3Rpb24gaXNIZXhDb2RlKGMpIHsKICByZXR1cm4gKChjLyogMCAqLyA+PSAweDMwKSAmJiAoYyA8PSAweDM5LyogOSAqLykpIHx8CiAgICAgICAgICgoYy8qIEEgKi8gPj0gMHg0MSkgJiYgKGMgPD0gMHg0Ni8qIEYgKi8pKSB8fAogICAgICAgICAoKGMvKiBhICovID49IDB4NjEpICYmIChjIDw9IDB4NjYvKiBmICovKSk7Cn0KCmZ1bmN0aW9uIGlzT2N0Q29kZShjKSB7CiAgcmV0dXJuICgoYy8qIDAgKi8gPj0gMHgzMCkgJiYgKGMgPD0gMHgzNy8qIDcgKi8pKTsKfQoKZnVuY3Rpb24gaXNEZWNDb2RlKGMpIHsKICByZXR1cm4gKChjLyogMCAqLyA+PSAweDMwKSAmJiAoYyA8PSAweDM5LyogOSAqLykpOwp9CgpmdW5jdGlvbiByZXNvbHZlWWFtbEludGVnZXIoZGF0YSkgewogIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gZmFsc2U7CgogIHZhciBtYXggPSBkYXRhLmxlbmd0aCwKICAgICAgaW5kZXggPSAwLAogICAgICBoYXNEaWdpdHMgPSBmYWxzZSwKICAgICAgY2g7CgogIGlmICghbWF4KSByZXR1cm4gZmFsc2U7CgogIGNoID0gZGF0YVtpbmRleF07CiAgaWYgKGNoID09PSAnLScgfHwgY2ggPT09ICcrJykgewogICAgY2ggPSBkYXRhWysraW5kZXhdOwogIH0KCiAgaWYgKGNoID09PSAnMCcpIHsKICAgIGlmIChpbmRleCArIDEgPT09IG1heCkgcmV0dXJuIHRydWU7CiAgICBjaCA9IGRhdGFbKytpbmRleF07CgogICAgaWYgKGNoID09PSAnYicpIHsKICAgICAgaW5kZXgrKzsKCiAgICAgIGZvciAoOyBpbmRleCA8IG1heDsgaW5kZXgrKykgewogICAgICAgIGNoID0gZGF0YVtpbmRleF07CiAgICAgICAgaWYgKGNoID09PSAnXycpIGNvbnRpbnVlOwogICAgICAgIGlmIChjaCAhPT0gJzAnICYmIGNoICE9PSAnMScpIHJldHVybiBmYWxzZTsKICAgICAgICBoYXNEaWdpdHMgPSB0cnVlOwogICAgICB9CiAgICAgIHJldHVybiBoYXNEaWdpdHMgJiYgY2ggIT09ICdfJzsKICAgIH0KCgogICAgaWYgKGNoID09PSAneCcpIHsKICAgICAgaW5kZXgrKzsKCiAgICAgIGZvciAoOyBpbmRleCA8IG1heDsgaW5kZXgrKykgewogICAgICAgIGNoID0gZGF0YVtpbmRleF07CiAgICAgICAgaWYgKGNoID09PSAnXycpIGNvbnRpbnVlOwogICAgICAgIGlmICghaXNIZXhDb2RlKGRhdGEuY2hhckNvZGVBdChpbmRleCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaGFzRGlnaXRzID0gdHJ1ZTsKICAgICAgfQogICAgICByZXR1cm4gaGFzRGlnaXRzICYmIGNoICE9PSAnXyc7CiAgICB9CiAgICBmb3IgKDsgaW5kZXggPCBtYXg7IGluZGV4KyspIHsKICAgICAgY2ggPSBkYXRhW2luZGV4XTsKICAgICAgaWYgKGNoID09PSAnXycpIGNvbnRpbnVlOwogICAgICBpZiAoIWlzT2N0Q29kZShkYXRhLmNoYXJDb2RlQXQoaW5kZXgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBoYXNEaWdpdHMgPSB0cnVlOwogICAgfQogICAgcmV0dXJuIGhhc0RpZ2l0cyAmJiBjaCAhPT0gJ18nOwogIH0KICBpZiAoY2ggPT09ICdfJykgcmV0dXJuIGZhbHNlOwoKICBmb3IgKDsgaW5kZXggPCBtYXg7IGluZGV4KyspIHsKICAgIGNoID0gZGF0YVtpbmRleF07CiAgICBpZiAoY2ggPT09ICdfJykgY29udGludWU7CiAgICBpZiAoY2ggPT09ICc6JykgYnJlYWs7CiAgICBpZiAoIWlzRGVjQ29kZShkYXRhLmNoYXJDb2RlQXQoaW5kZXgpKSkgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBoYXNEaWdpdHMgPSB0cnVlOwogIH0KICBpZiAoIWhhc0RpZ2l0cyB8fCBjaCA9PT0gJ18nKSByZXR1cm4gZmFsc2U7CiAgaWYgKGNoICE9PSAnOicpIHJldHVybiB0cnVlOwogIHJldHVybiAvXig6WzAtNV0/WzAtOV0pKyQvLnRlc3QoZGF0YS5zbGljZShpbmRleCkpOwp9CgpmdW5jdGlvbiBjb25zdHJ1Y3RZYW1sSW50ZWdlcihkYXRhKSB7CiAgdmFyIHZhbHVlID0gZGF0YSwgc2lnbiA9IDEsIGNoLCBiYXNlLCBkaWdpdHMgPSBbXTsKCiAgaWYgKHZhbHVlLmluZGV4T2YoJ18nKSAhPT0gLTEpIHsKICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZSgvXy9nLCAnJyk7CiAgfQoKICBjaCA9IHZhbHVlWzBdOwoKICBpZiAoY2ggPT09ICctJyB8fCBjaCA9PT0gJysnKSB7CiAgICBpZiAoY2ggPT09ICctJykgc2lnbiA9IC0xOwogICAgdmFsdWUgPSB2YWx1ZS5zbGljZSgxKTsKICAgIGNoID0gdmFsdWVbMF07CiAgfQoKICBpZiAodmFsdWUgPT09ICcwJykgcmV0dXJuIDA7CgogIGlmIChjaCA9PT0gJzAnKSB7CiAgICBpZiAodmFsdWVbMV0gPT09ICdiJykgcmV0dXJuIHNpZ24gKiBwYXJzZUludCh2YWx1ZS5zbGljZSgyKSwgMik7CiAgICBpZiAodmFsdWVbMV0gPT09ICd4JykgcmV0dXJuIHNpZ24gKiBwYXJzZUludCh2YWx1ZSwgMTYpOwogICAgcmV0dXJuIHNpZ24gKiBwYXJzZUludCh2YWx1ZSwgOCk7CiAgfQoKICBpZiAodmFsdWUuaW5kZXhPZignOicpICE9PSAtMSkgewogICAgdmFsdWUuc3BsaXQoJzonKS5mb3JFYWNoKGZ1bmN0aW9uICh2KSB7CiAgICAgIGRpZ2l0cy51bnNoaWZ0KHBhcnNlSW50KHYsIDEwKSk7CiAgICB9KTsKCiAgICB2YWx1ZSA9IDA7CiAgICBiYXNlID0gMTsKCiAgICBkaWdpdHMuZm9yRWFjaChmdW5jdGlvbiAoZCkgewogICAgICB2YWx1ZSArPSAoZCAqIGJhc2UpOwogICAgICBiYXNlICo9IDYwOwogICAgfSk7CgogICAgcmV0dXJuIHNpZ24gKiB2YWx1ZTsKCiAgfQoKICByZXR1cm4gc2lnbiAqIHBhcnNlSW50KHZhbHVlLCAxMCk7Cn0KCmZ1bmN0aW9uIGlzSW50ZWdlcihvYmplY3QpIHsKICByZXR1cm4gKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmplY3QpKSA9PT0gJ1tvYmplY3QgTnVtYmVyXScgJiYKICAgICAgICAgKG9iamVjdCAlIDEgPT09IDAgJiYgIWNvbW1vbi5pc05lZ2F0aXZlWmVybyhvYmplY3QpKTsKfQoKbW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6aW50JywgewogIGtpbmQ6ICdzY2FsYXInLAogIHJlc29sdmU6IHJlc29sdmVZYW1sSW50ZWdlciwKICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdFlhbWxJbnRlZ2VyLAogIHByZWRpY2F0ZTogaXNJbnRlZ2VyLAogIHJlcHJlc2VudDogewogICAgYmluYXJ5OiAgICAgIGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIG9iaiA+PSAwID8gJzBiJyArIG9iai50b1N0cmluZygyKSA6ICctMGInICsgb2JqLnRvU3RyaW5nKDIpLnNsaWNlKDEpOyB9LAogICAgb2N0YWw6ICAgICAgIGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIG9iaiA+PSAwID8gJzAnICArIG9iai50b1N0cmluZyg4KSA6ICctMCcgICsgb2JqLnRvU3RyaW5nKDgpLnNsaWNlKDEpOyB9LAogICAgZGVjaW1hbDogICAgIGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIG9iai50b1N0cmluZygxMCk7IH0sCiAgICBoZXhhZGVjaW1hbDogZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gb2JqID49IDAgPyAnMHgnICsgb2JqLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpIDogICctMHgnICsgb2JqLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpLnNsaWNlKDEpOyB9CiAgfSwKICBkZWZhdWx0U3R5bGU6ICdkZWNpbWFsJywKICBzdHlsZUFsaWFzZXM6IHsKICAgIGJpbmFyeTogICAgICBbIDIsICAnYmluJyBdLAogICAgb2N0YWw6ICAgICAgIFsgOCwgICdvY3QnIF0sCiAgICBkZWNpbWFsOiAgICAgWyAxMCwgJ2RlYycgXSwKICAgIGhleGFkZWNpbWFsOiBbIDE2LCAnaGV4JyBdCiAgfQp9KTsKCn0seyIuLi9jb21tb24iOjUsIi4uL3R5cGUiOjE2fV0sMjE6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7Cgp2YXIgZXNwcmltYTsKdHJ5IHsKICB2YXIgX3JlcXVpcmUgPSByZXF1aXJlOwogIGVzcHJpbWEgPSBfcmVxdWlyZSgnZXNwcmltYScpOwp9IGNhdGNoIChfKSB7CiAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSBlc3ByaW1hID0gd2luZG93LmVzcHJpbWE7Cn0KCnZhciBUeXBlID0gcmVxdWlyZSgnLi4vLi4vdHlwZScpOwoKZnVuY3Rpb24gcmVzb2x2ZUphdmFzY3JpcHRGdW5jdGlvbihkYXRhKSB7CiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiBmYWxzZTsKCiAgdHJ5IHsKICAgIHZhciBzb3VyY2UgPSAnKCcgKyBkYXRhICsgJyknLAogICAgICAgIGFzdCAgICA9IGVzcHJpbWEucGFyc2Uoc291cmNlLCB7IHJhbmdlOiB0cnVlIH0pOwoKICAgIGlmIChhc3QudHlwZSAgICAgICAgICAgICAgICAgICAgIT09ICdQcm9ncmFtJyAgICAgICAgICAgICB8fAogICAgICAgIGFzdC5ib2R5Lmxlbmd0aCAgICAgICAgICAgICAhPT0gMSAgICAgICAgICAgICAgICAgICAgIHx8CiAgICAgICAgYXN0LmJvZHlbMF0udHlwZSAgICAgICAgICAgICE9PSAnRXhwcmVzc2lvblN0YXRlbWVudCcgfHwKICAgICAgICAoYXN0LmJvZHlbMF0uZXhwcmVzc2lvbi50eXBlICE9PSAnQXJyb3dGdW5jdGlvbkV4cHJlc3Npb24nICYmCiAgICAgICAgICBhc3QuYm9keVswXS5leHByZXNzaW9uLnR5cGUgIT09ICdGdW5jdGlvbkV4cHJlc3Npb24nKSkgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgcmV0dXJuIHRydWU7CiAgfSBjYXRjaCAoZXJyKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQp9CgpmdW5jdGlvbiBjb25zdHJ1Y3RKYXZhc2NyaXB0RnVuY3Rpb24oZGF0YSkgewogIHJldHVybiBmdW5jdGlvbigpIHt9Cn0KCmZ1bmN0aW9uIHJlcHJlc2VudEphdmFzY3JpcHRGdW5jdGlvbihvYmplY3QgLyosIHN0eWxlKi8pIHsKICByZXR1cm4gb2JqZWN0LnRvU3RyaW5nKCk7Cn0KCmZ1bmN0aW9uIGlzRnVuY3Rpb24ob2JqZWN0KSB7CiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmplY3QpID09PSAnW29iamVjdCBGdW5jdGlvbl0nOwp9Cgptb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpqcy9mdW5jdGlvbicsIHsKICBraW5kOiAnc2NhbGFyJywKICByZXNvbHZlOiByZXNvbHZlSmF2YXNjcmlwdEZ1bmN0aW9uLAogIGNvbnN0cnVjdDogY29uc3RydWN0SmF2YXNjcmlwdEZ1bmN0aW9uLAogIHByZWRpY2F0ZTogaXNGdW5jdGlvbiwKICByZXByZXNlbnQ6IHJlcHJlc2VudEphdmFzY3JpcHRGdW5jdGlvbgp9KTsKCn0seyIuLi8uLi90eXBlIjoxNn1dLDIyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKdmFyIFR5cGUgPSByZXF1aXJlKCcuLi8uLi90eXBlJyk7CgpmdW5jdGlvbiByZXNvbHZlSmF2YXNjcmlwdFJlZ0V4cChkYXRhKSB7CiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiBmYWxzZTsKICBpZiAoZGF0YS5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTsKCiAgdmFyIHJlZ2V4cCA9IGRhdGEsCiAgICAgIHRhaWwgICA9IC9cLyhbZ2ltXSopJC8uZXhlYyhkYXRhKSwKICAgICAgbW9kaWZpZXJzID0gJyc7CiAgaWYgKHJlZ2V4cFswXSA9PT0gJy8nKSB7CiAgICBpZiAodGFpbCkgbW9kaWZpZXJzID0gdGFpbFsxXTsKCiAgICBpZiAobW9kaWZpZXJzLmxlbmd0aCA+IDMpIHJldHVybiBmYWxzZTsKICAgIGlmIChyZWdleHBbcmVnZXhwLmxlbmd0aCAtIG1vZGlmaWVycy5sZW5ndGggLSAxXSAhPT0gJy8nKSByZXR1cm4gZmFsc2U7CiAgfQoKICByZXR1cm4gdHJ1ZTsKfQoKZnVuY3Rpb24gY29uc3RydWN0SmF2YXNjcmlwdFJlZ0V4cChkYXRhKSB7CiAgdmFyIHJlZ2V4cCA9IGRhdGEsCiAgICAgIHRhaWwgICA9IC9cLyhbZ2ltXSopJC8uZXhlYyhkYXRhKSwKICAgICAgbW9kaWZpZXJzID0gJyc7CiAgaWYgKHJlZ2V4cFswXSA9PT0gJy8nKSB7CiAgICBpZiAodGFpbCkgbW9kaWZpZXJzID0gdGFpbFsxXTsKICAgIHJlZ2V4cCA9IHJlZ2V4cC5zbGljZSgxLCByZWdleHAubGVuZ3RoIC0gbW9kaWZpZXJzLmxlbmd0aCAtIDEpOwogIH0KCiAgcmV0dXJuIG5ldyBSZWdFeHAocmVnZXhwLCBtb2RpZmllcnMpOwp9CgpmdW5jdGlvbiByZXByZXNlbnRKYXZhc2NyaXB0UmVnRXhwKG9iamVjdCAvKiwgc3R5bGUqLykgewogIHZhciByZXN1bHQgPSAnLycgKyBvYmplY3Quc291cmNlICsgJy8nOwoKICBpZiAob2JqZWN0Lmdsb2JhbCkgcmVzdWx0ICs9ICdnJzsKICBpZiAob2JqZWN0Lm11bHRpbGluZSkgcmVzdWx0ICs9ICdtJzsKICBpZiAob2JqZWN0Lmlnbm9yZUNhc2UpIHJlc3VsdCArPSAnaSc7CgogIHJldHVybiByZXN1bHQ7Cn0KCmZ1bmN0aW9uIGlzUmVnRXhwKG9iamVjdCkgewogIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqZWN0KSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7Cn0KCm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmpzL3JlZ2V4cCcsIHsKICBraW5kOiAnc2NhbGFyJywKICByZXNvbHZlOiByZXNvbHZlSmF2YXNjcmlwdFJlZ0V4cCwKICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdEphdmFzY3JpcHRSZWdFeHAsCiAgcHJlZGljYXRlOiBpc1JlZ0V4cCwKICByZXByZXNlbnQ6IHJlcHJlc2VudEphdmFzY3JpcHRSZWdFeHAKfSk7Cgp9LHsiLi4vLi4vdHlwZSI6MTZ9XSwyMzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCnZhciBUeXBlID0gcmVxdWlyZSgnLi4vLi4vdHlwZScpOwoKZnVuY3Rpb24gcmVzb2x2ZUphdmFzY3JpcHRVbmRlZmluZWQoKSB7CiAgcmV0dXJuIHRydWU7Cn0KCmZ1bmN0aW9uIGNvbnN0cnVjdEphdmFzY3JpcHRVbmRlZmluZWQoKSB7CiAgcmV0dXJuIHVuZGVmaW5lZDsKfQoKZnVuY3Rpb24gcmVwcmVzZW50SmF2YXNjcmlwdFVuZGVmaW5lZCgpIHsKICByZXR1cm4gJyc7Cn0KCmZ1bmN0aW9uIGlzVW5kZWZpbmVkKG9iamVjdCkgewogIHJldHVybiB0eXBlb2Ygb2JqZWN0ID09PSAndW5kZWZpbmVkJzsKfQoKbW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6anMvdW5kZWZpbmVkJywgewogIGtpbmQ6ICdzY2FsYXInLAogIHJlc29sdmU6IHJlc29sdmVKYXZhc2NyaXB0VW5kZWZpbmVkLAogIGNvbnN0cnVjdDogY29uc3RydWN0SmF2YXNjcmlwdFVuZGVmaW5lZCwKICBwcmVkaWNhdGU6IGlzVW5kZWZpbmVkLAogIHJlcHJlc2VudDogcmVwcmVzZW50SmF2YXNjcmlwdFVuZGVmaW5lZAp9KTsKCn0seyIuLi8uLi90eXBlIjoxNn1dLDI0OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKdmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7Cgptb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjptYXAnLCB7CiAga2luZDogJ21hcHBpbmcnLAogIGNvbnN0cnVjdDogZnVuY3Rpb24gKGRhdGEpIHsgcmV0dXJuIGRhdGEgIT09IG51bGwgPyBkYXRhIDoge307IH0KfSk7Cgp9LHsiLi4vdHlwZSI6MTZ9XSwyNTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7Cid1c2Ugc3RyaWN0JzsKCnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpOwoKZnVuY3Rpb24gcmVzb2x2ZVlhbWxNZXJnZShkYXRhKSB7CiAgcmV0dXJuIGRhdGEgPT09ICc8PCcgfHwgZGF0YSA9PT0gbnVsbDsKfQoKbW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6bWVyZ2UnLCB7CiAga2luZDogJ3NjYWxhcicsCiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxNZXJnZQp9KTsKCn0seyIuLi90eXBlIjoxNn1dLDI2OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKdmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7CgpmdW5jdGlvbiByZXNvbHZlWWFtbE51bGwoZGF0YSkgewogIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gdHJ1ZTsKCiAgdmFyIG1heCA9IGRhdGEubGVuZ3RoOwoKICByZXR1cm4gKG1heCA9PT0gMSAmJiBkYXRhID09PSAnficpIHx8CiAgICAgICAgIChtYXggPT09IDQgJiYgKGRhdGEgPT09ICdudWxsJyB8fCBkYXRhID09PSAnTnVsbCcgfHwgZGF0YSA9PT0gJ05VTEwnKSk7Cn0KCmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxOdWxsKCkgewogIHJldHVybiBudWxsOwp9CgpmdW5jdGlvbiBpc051bGwob2JqZWN0KSB7CiAgcmV0dXJuIG9iamVjdCA9PT0gbnVsbDsKfQoKbW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6bnVsbCcsIHsKICBraW5kOiAnc2NhbGFyJywKICByZXNvbHZlOiByZXNvbHZlWWFtbE51bGwsCiAgY29uc3RydWN0OiBjb25zdHJ1Y3RZYW1sTnVsbCwKICBwcmVkaWNhdGU6IGlzTnVsbCwKICByZXByZXNlbnQ6IHsKICAgIGNhbm9uaWNhbDogZnVuY3Rpb24gKCkgeyByZXR1cm4gJ34nOyAgICB9LAogICAgbG93ZXJjYXNlOiBmdW5jdGlvbiAoKSB7IHJldHVybiAnbnVsbCc7IH0sCiAgICB1cHBlcmNhc2U6IGZ1bmN0aW9uICgpIHsgcmV0dXJuICdOVUxMJzsgfSwKICAgIGNhbWVsY2FzZTogZnVuY3Rpb24gKCkgeyByZXR1cm4gJ051bGwnOyB9CiAgfSwKICBkZWZhdWx0U3R5bGU6ICdsb3dlcmNhc2UnCn0pOwoKfSx7Ii4uL3R5cGUiOjE2fV0sMjc6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7Cgp2YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTsKCnZhciBfaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5Owp2YXIgX3RvU3RyaW5nICAgICAgID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZzsKCmZ1bmN0aW9uIHJlc29sdmVZYW1sT21hcChkYXRhKSB7CiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiB0cnVlOwoKICB2YXIgb2JqZWN0S2V5cyA9IFtdLCBpbmRleCwgbGVuZ3RoLCBwYWlyLCBwYWlyS2V5LCBwYWlySGFzS2V5LAogICAgICBvYmplY3QgPSBkYXRhOwoKICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gb2JqZWN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHsKICAgIHBhaXIgPSBvYmplY3RbaW5kZXhdOwogICAgcGFpckhhc0tleSA9IGZhbHNlOwoKICAgIGlmIChfdG9TdHJpbmcuY2FsbChwYWlyKSAhPT0gJ1tvYmplY3QgT2JqZWN0XScpIHJldHVybiBmYWxzZTsKCiAgICBmb3IgKHBhaXJLZXkgaW4gcGFpcikgewogICAgICBpZiAoX2hhc093blByb3BlcnR5LmNhbGwocGFpciwgcGFpcktleSkpIHsKICAgICAgICBpZiAoIXBhaXJIYXNLZXkpIHBhaXJIYXNLZXkgPSB0cnVlOwogICAgICAgIGVsc2UgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICB9CgogICAgaWYgKCFwYWlySGFzS2V5KSByZXR1cm4gZmFsc2U7CgogICAgaWYgKG9iamVjdEtleXMuaW5kZXhPZihwYWlyS2V5KSA9PT0gLTEpIG9iamVjdEtleXMucHVzaChwYWlyS2V5KTsKICAgIGVsc2UgcmV0dXJuIGZhbHNlOwogIH0KCiAgcmV0dXJuIHRydWU7Cn0KCmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxPbWFwKGRhdGEpIHsKICByZXR1cm4gZGF0YSAhPT0gbnVsbCA/IGRhdGEgOiBbXTsKfQoKbW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6b21hcCcsIHsKICBraW5kOiAnc2VxdWVuY2UnLAogIHJlc29sdmU6IHJlc29sdmVZYW1sT21hcCwKICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdFlhbWxPbWFwCn0pOwoKfSx7Ii4uL3R5cGUiOjE2fV0sMjg6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7Cgp2YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTsKCnZhciBfdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nOwoKZnVuY3Rpb24gcmVzb2x2ZVlhbWxQYWlycyhkYXRhKSB7CiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiB0cnVlOwoKICB2YXIgaW5kZXgsIGxlbmd0aCwgcGFpciwga2V5cywgcmVzdWx0LAogICAgICBvYmplY3QgPSBkYXRhOwoKICByZXN1bHQgPSBuZXcgQXJyYXkob2JqZWN0Lmxlbmd0aCk7CgogIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkgewogICAgcGFpciA9IG9iamVjdFtpbmRleF07CgogICAgaWYgKF90b1N0cmluZy5jYWxsKHBhaXIpICE9PSAnW29iamVjdCBPYmplY3RdJykgcmV0dXJuIGZhbHNlOwoKICAgIGtleXMgPSBPYmplY3Qua2V5cyhwYWlyKTsKCiAgICBpZiAoa2V5cy5sZW5ndGggIT09IDEpIHJldHVybiBmYWxzZTsKCiAgICByZXN1bHRbaW5kZXhdID0gWyBrZXlzWzBdLCBwYWlyW2tleXNbMF1dIF07CiAgfQoKICByZXR1cm4gdHJ1ZTsKfQoKZnVuY3Rpb24gY29uc3RydWN0WWFtbFBhaXJzKGRhdGEpIHsKICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIFtdOwoKICB2YXIgaW5kZXgsIGxlbmd0aCwgcGFpciwga2V5cywgcmVzdWx0LAogICAgICBvYmplY3QgPSBkYXRhOwoKICByZXN1bHQgPSBuZXcgQXJyYXkob2JqZWN0Lmxlbmd0aCk7CgogIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkgewogICAgcGFpciA9IG9iamVjdFtpbmRleF07CgogICAga2V5cyA9IE9iamVjdC5rZXlzKHBhaXIpOwoKICAgIHJlc3VsdFtpbmRleF0gPSBbIGtleXNbMF0sIHBhaXJba2V5c1swXV0gXTsKICB9CgogIHJldHVybiByZXN1bHQ7Cn0KCm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOnBhaXJzJywgewogIGtpbmQ6ICdzZXF1ZW5jZScsCiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxQYWlycywKICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdFlhbWxQYWlycwp9KTsKCn0seyIuLi90eXBlIjoxNn1dLDI5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKdmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7Cgptb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpzZXEnLCB7CiAga2luZDogJ3NlcXVlbmNlJywKICBjb25zdHJ1Y3Q6IGZ1bmN0aW9uIChkYXRhKSB7IHJldHVybiBkYXRhICE9PSBudWxsID8gZGF0YSA6IFtdOyB9Cn0pOwoKfSx7Ii4uL3R5cGUiOjE2fV0sMzA6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewondXNlIHN0cmljdCc7Cgp2YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTsKCnZhciBfaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5OwoKZnVuY3Rpb24gcmVzb2x2ZVlhbWxTZXQoZGF0YSkgewogIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gdHJ1ZTsKCiAgdmFyIGtleSwgb2JqZWN0ID0gZGF0YTsKCiAgZm9yIChrZXkgaW4gb2JqZWN0KSB7CiAgICBpZiAoX2hhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSB7CiAgICAgIGlmIChvYmplY3Rba2V5XSAhPT0gbnVsbCkgcmV0dXJuIGZhbHNlOwogICAgfQogIH0KCiAgcmV0dXJuIHRydWU7Cn0KCmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxTZXQoZGF0YSkgewogIHJldHVybiBkYXRhICE9PSBudWxsID8gZGF0YSA6IHt9Owp9Cgptb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpzZXQnLCB7CiAga2luZDogJ21hcHBpbmcnLAogIHJlc29sdmU6IHJlc29sdmVZYW1sU2V0LAogIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbFNldAp9KTsKCn0seyIuLi90eXBlIjoxNn1dLDMxOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKdmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7Cgptb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpzdHInLCB7CiAga2luZDogJ3NjYWxhcicsCiAgY29uc3RydWN0OiBmdW5jdGlvbiAoZGF0YSkgeyByZXR1cm4gZGF0YSAhPT0gbnVsbCA/IGRhdGEgOiAnJzsgfQp9KTsKCn0seyIuLi90eXBlIjoxNn1dLDMyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsKJ3VzZSBzdHJpY3QnOwoKdmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7Cgp2YXIgWUFNTF9EQVRFX1JFR0VYUCA9IG5ldyBSZWdFeHAoCiAgJ14oWzAtOV1bMC05XVswLTldWzAtOV0pJyAgICAgICAgICArIC8vIFsxXSB5ZWFyCiAgJy0oWzAtOV1bMC05XSknICAgICAgICAgICAgICAgICAgICArIC8vIFsyXSBtb250aAogICctKFswLTldWzAtOV0pJCcpOyAgICAgICAgICAgICAgICAgICAvLyBbM10gZGF5Cgp2YXIgWUFNTF9USU1FU1RBTVBfUkVHRVhQID0gbmV3IFJlZ0V4cCgKICAnXihbMC05XVswLTldWzAtOV1bMC05XSknICAgICAgICAgICsgLy8gWzFdIHllYXIKICAnLShbMC05XVswLTldPyknICAgICAgICAgICAgICAgICAgICsgLy8gWzJdIG1vbnRoCiAgJy0oWzAtOV1bMC05XT8pJyAgICAgICAgICAgICAgICAgICArIC8vIFszXSBkYXkKICAnKD86W1R0XXxbIFxcdF0rKScgICAgICAgICAgICAgICAgICsgLy8gLi4uCiAgJyhbMC05XVswLTldPyknICAgICAgICAgICAgICAgICAgICArIC8vIFs0XSBob3VyCiAgJzooWzAtOV1bMC05XSknICAgICAgICAgICAgICAgICAgICArIC8vIFs1XSBtaW51dGUKICAnOihbMC05XVswLTldKScgICAgICAgICAgICAgICAgICAgICsgLy8gWzZdIHNlY29uZAogICcoPzpcXC4oWzAtOV0qKSk/JyAgICAgICAgICAgICAgICAgKyAvLyBbN10gZnJhY3Rpb24KICAnKD86WyBcXHRdKihafChbLStdKShbMC05XVswLTldPyknICsgLy8gWzhdIHR6IFs5XSB0el9zaWduIFsxMF0gdHpfaG91cgogICcoPzo6KFswLTldWzAtOV0pKT8pKT8kJyk7ICAgICAgICAgICAvLyBbMTFdIHR6X21pbnV0ZQoKZnVuY3Rpb24gcmVzb2x2ZVlhbWxUaW1lc3RhbXAoZGF0YSkgewogIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gZmFsc2U7CiAgaWYgKFlBTUxfREFURV9SRUdFWFAuZXhlYyhkYXRhKSAhPT0gbnVsbCkgcmV0dXJuIHRydWU7CiAgaWYgKFlBTUxfVElNRVNUQU1QX1JFR0VYUC5leGVjKGRhdGEpICE9PSBudWxsKSByZXR1cm4gdHJ1ZTsKICByZXR1cm4gZmFsc2U7Cn0KCmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxUaW1lc3RhbXAoZGF0YSkgewogIHZhciBtYXRjaCwgeWVhciwgbW9udGgsIGRheSwgaG91ciwgbWludXRlLCBzZWNvbmQsIGZyYWN0aW9uID0gMCwKICAgICAgZGVsdGEgPSBudWxsLCB0el9ob3VyLCB0el9taW51dGUsIGRhdGU7CgogIG1hdGNoID0gWUFNTF9EQVRFX1JFR0VYUC5leGVjKGRhdGEpOwogIGlmIChtYXRjaCA9PT0gbnVsbCkgbWF0Y2ggPSBZQU1MX1RJTUVTVEFNUF9SRUdFWFAuZXhlYyhkYXRhKTsKCiAgaWYgKG1hdGNoID09PSBudWxsKSB0aHJvdyBuZXcgRXJyb3IoJ0RhdGUgcmVzb2x2ZSBlcnJvcicpOwoKICB5ZWFyID0gKyhtYXRjaFsxXSk7CiAgbW9udGggPSArKG1hdGNoWzJdKSAtIDE7IC8vIEpTIG1vbnRoIHN0YXJ0cyB3aXRoIDAKICBkYXkgPSArKG1hdGNoWzNdKTsKCiAgaWYgKCFtYXRjaFs0XSkgeyAvLyBubyBob3VyCiAgICByZXR1cm4gbmV3IERhdGUoRGF0ZS5VVEMoeWVhciwgbW9udGgsIGRheSkpOwogIH0KCiAgaG91ciA9ICsobWF0Y2hbNF0pOwogIG1pbnV0ZSA9ICsobWF0Y2hbNV0pOwogIHNlY29uZCA9ICsobWF0Y2hbNl0pOwoKICBpZiAobWF0Y2hbN10pIHsKICAgIGZyYWN0aW9uID0gbWF0Y2hbN10uc2xpY2UoMCwgMyk7CiAgICB3aGlsZSAoZnJhY3Rpb24ubGVuZ3RoIDwgMykgeyAvLyBtaWxsaS1zZWNvbmRzCiAgICAgIGZyYWN0aW9uICs9ICcwJzsKICAgIH0KICAgIGZyYWN0aW9uID0gK2ZyYWN0aW9uOwogIH0KCiAgaWYgKG1hdGNoWzldKSB7CiAgICB0el9ob3VyID0gKyhtYXRjaFsxMF0pOwogICAgdHpfbWludXRlID0gKyhtYXRjaFsxMV0gfHwgMCk7CiAgICBkZWx0YSA9ICh0el9ob3VyICogNjAgKyB0el9taW51dGUpICogNjAwMDA7IC8vIGRlbHRhIGluIG1pbGktc2Vjb25kcwogICAgaWYgKG1hdGNoWzldID09PSAnLScpIGRlbHRhID0gLWRlbHRhOwogIH0KCiAgZGF0ZSA9IG5ldyBEYXRlKERhdGUuVVRDKHllYXIsIG1vbnRoLCBkYXksIGhvdXIsIG1pbnV0ZSwgc2Vjb25kLCBmcmFjdGlvbikpOwoKICBpZiAoZGVsdGEpIGRhdGUuc2V0VGltZShkYXRlLmdldFRpbWUoKSAtIGRlbHRhKTsKCiAgcmV0dXJuIGRhdGU7Cn0KCmZ1bmN0aW9uIHJlcHJlc2VudFlhbWxUaW1lc3RhbXAob2JqZWN0IC8qLCBzdHlsZSovKSB7CiAgcmV0dXJuIG9iamVjdC50b0lTT1N0cmluZygpOwp9Cgptb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjp0aW1lc3RhbXAnLCB7CiAga2luZDogJ3NjYWxhcicsCiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxUaW1lc3RhbXAsCiAgY29uc3RydWN0OiBjb25zdHJ1Y3RZYW1sVGltZXN0YW1wLAogIGluc3RhbmNlT2Y6IERhdGUsCiAgcmVwcmVzZW50OiByZXByZXNlbnRZYW1sVGltZXN0YW1wCn0pOwoKfSx7Ii4uL3R5cGUiOjE2fV0sMzM6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpewooZnVuY3Rpb24gKGdsb2JhbCl7CnZhciBMQVJHRV9BUlJBWV9TSVpFID0gMjAwOwp2YXIgSEFTSF9VTkRFRklORUQgPSAnX19sb2Rhc2hfaGFzaF91bmRlZmluZWRfXyc7CnZhciBIT1RfQ09VTlQgPSA4MDAsCiAgICBIT1RfU1BBTiA9IDE2Owp2YXIgTUFYX1NBRkVfSU5URUdFUiA9IDkwMDcxOTkyNTQ3NDA5OTE7CnZhciBhcmdzVGFnID0gJ1tvYmplY3QgQXJndW1lbnRzXScsCiAgICBhcnJheVRhZyA9ICdbb2JqZWN0IEFycmF5XScsCiAgICBhc3luY1RhZyA9ICdbb2JqZWN0IEFzeW5jRnVuY3Rpb25dJywKICAgIGJvb2xUYWcgPSAnW29iamVjdCBCb29sZWFuXScsCiAgICBkYXRlVGFnID0gJ1tvYmplY3QgRGF0ZV0nLAogICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLAogICAgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXScsCiAgICBnZW5UYWcgPSAnW29iamVjdCBHZW5lcmF0b3JGdW5jdGlvbl0nLAogICAgbWFwVGFnID0gJ1tvYmplY3QgTWFwXScsCiAgICBudW1iZXJUYWcgPSAnW29iamVjdCBOdW1iZXJdJywKICAgIG51bGxUYWcgPSAnW29iamVjdCBOdWxsXScsCiAgICBvYmplY3RUYWcgPSAnW29iamVjdCBPYmplY3RdJywKICAgIHByb3h5VGFnID0gJ1tvYmplY3QgUHJveHldJywKICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLAogICAgc2V0VGFnID0gJ1tvYmplY3QgU2V0XScsCiAgICBzdHJpbmdUYWcgPSAnW29iamVjdCBTdHJpbmddJywKICAgIHVuZGVmaW5lZFRhZyA9ICdbb2JqZWN0IFVuZGVmaW5lZF0nLAogICAgd2Vha01hcFRhZyA9ICdbb2JqZWN0IFdlYWtNYXBdJzsKCnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsCiAgICBkYXRhVmlld1RhZyA9ICdbb2JqZWN0IERhdGFWaWV3XScsCiAgICBmbG9hdDMyVGFnID0gJ1tvYmplY3QgRmxvYXQzMkFycmF5XScsCiAgICBmbG9hdDY0VGFnID0gJ1tvYmplY3QgRmxvYXQ2NEFycmF5XScsCiAgICBpbnQ4VGFnID0gJ1tvYmplY3QgSW50OEFycmF5XScsCiAgICBpbnQxNlRhZyA9ICdbb2JqZWN0IEludDE2QXJyYXldJywKICAgIGludDMyVGFnID0gJ1tvYmplY3QgSW50MzJBcnJheV0nLAogICAgdWludDhUYWcgPSAnW29iamVjdCBVaW50OEFycmF5XScsCiAgICB1aW50OENsYW1wZWRUYWcgPSAnW29iamVjdCBVaW50OENsYW1wZWRBcnJheV0nLAogICAgdWludDE2VGFnID0gJ1tvYmplY3QgVWludDE2QXJyYXldJywKICAgIHVpbnQzMlRhZyA9ICdbb2JqZWN0IFVpbnQzMkFycmF5XSc7CnZhciByZVJlZ0V4cENoYXIgPSAvW1xcXiQuKis/KClbXF17fXxdL2c7CnZhciByZUlzSG9zdEN0b3IgPSAvXlxbb2JqZWN0IC4rP0NvbnN0cnVjdG9yXF0kLzsKdmFyIHJlSXNVaW50ID0gL14oPzowfFsxLTldXGQqKSQvOwp2YXIgdHlwZWRBcnJheVRhZ3MgPSB7fTsKdHlwZWRBcnJheVRhZ3NbZmxvYXQzMlRhZ10gPSB0eXBlZEFycmF5VGFnc1tmbG9hdDY0VGFnXSA9CnR5cGVkQXJyYXlUYWdzW2ludDhUYWddID0gdHlwZWRBcnJheVRhZ3NbaW50MTZUYWddID0KdHlwZWRBcnJheVRhZ3NbaW50MzJUYWddID0gdHlwZWRBcnJheVRhZ3NbdWludDhUYWddID0KdHlwZWRBcnJheVRhZ3NbdWludDhDbGFtcGVkVGFnXSA9IHR5cGVkQXJyYXlUYWdzW3VpbnQxNlRhZ10gPQp0eXBlZEFycmF5VGFnc1t1aW50MzJUYWddID0gdHJ1ZTsKdHlwZWRBcnJheVRhZ3NbYXJnc1RhZ10gPSB0eXBlZEFycmF5VGFnc1thcnJheVRhZ10gPQp0eXBlZEFycmF5VGFnc1thcnJheUJ1ZmZlclRhZ10gPSB0eXBlZEFycmF5VGFnc1tib29sVGFnXSA9CnR5cGVkQXJyYXlUYWdzW2RhdGFWaWV3VGFnXSA9IHR5cGVkQXJyYXlUYWdzW2RhdGVUYWddID0KdHlwZWRBcnJheVRhZ3NbZXJyb3JUYWddID0gdHlwZWRBcnJheVRhZ3NbZnVuY1RhZ10gPQp0eXBlZEFycmF5VGFnc1ttYXBUYWddID0gdHlwZWRBcnJheVRhZ3NbbnVtYmVyVGFnXSA9CnR5cGVkQXJyYXlUYWdzW29iamVjdFRhZ10gPSB0eXBlZEFycmF5VGFnc1tyZWdleHBUYWddID0KdHlwZWRBcnJheVRhZ3Nbc2V0VGFnXSA9IHR5cGVkQXJyYXlUYWdzW3N0cmluZ1RhZ10gPQp0eXBlZEFycmF5VGFnc1t3ZWFrTWFwVGFnXSA9IGZhbHNlOwp2YXIgZnJlZUdsb2JhbCA9IHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsICYmIGdsb2JhbC5PYmplY3QgPT09IE9iamVjdCAmJiBnbG9iYWw7CnZhciBmcmVlU2VsZiA9IHR5cGVvZiBzZWxmID09ICdvYmplY3QnICYmIHNlbGYgJiYgc2VsZi5PYmplY3QgPT09IE9iamVjdCAmJiBzZWxmOwp2YXIgcm9vdCA9IGZyZWVHbG9iYWwgfHwgZnJlZVNlbGYgfHwgRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTsKdmFyIGZyZWVFeHBvcnRzID0gdHlwZW9mIGV4cG9ydHMgPT0gJ29iamVjdCcgJiYgZXhwb3J0cyAmJiAhZXhwb3J0cy5ub2RlVHlwZSAmJiBleHBvcnRzOwp2YXIgZnJlZU1vZHVsZSA9IGZyZWVFeHBvcnRzICYmIHR5cGVvZiBtb2R1bGUgPT0gJ29iamVjdCcgJiYgbW9kdWxlICYmICFtb2R1bGUubm9kZVR5cGUgJiYgbW9kdWxlOwp2YXIgbW9kdWxlRXhwb3J0cyA9IGZyZWVNb2R1bGUgJiYgZnJlZU1vZHVsZS5leHBvcnRzID09PSBmcmVlRXhwb3J0czsKdmFyIGZyZWVQcm9jZXNzID0gbW9kdWxlRXhwb3J0cyAmJiBmcmVlR2xvYmFsLnByb2Nlc3M7CnZhciBub2RlVXRpbCA9IChmdW5jdGlvbigpIHsKICB0cnkgewogICAgcmV0dXJuIGZyZWVQcm9jZXNzICYmIGZyZWVQcm9jZXNzLmJpbmRpbmcgJiYgZnJlZVByb2Nlc3MuYmluZGluZygndXRpbCcpOwogIH0gY2F0Y2ggKGUpIHt9Cn0oKSk7CnZhciBub2RlSXNUeXBlZEFycmF5ID0gbm9kZVV0aWwgJiYgbm9kZVV0aWwuaXNUeXBlZEFycmF5OwpmdW5jdGlvbiBhcHBseShmdW5jLCB0aGlzQXJnLCBhcmdzKSB7CiAgc3dpdGNoIChhcmdzLmxlbmd0aCkgewogICAgY2FzZSAwOiByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcpOwogICAgY2FzZSAxOiByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIGFyZ3NbMF0pOwogICAgY2FzZSAyOiByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIGFyZ3NbMF0sIGFyZ3NbMV0pOwogICAgY2FzZSAzOiByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pOwogIH0KICByZXR1cm4gZnVuYy5hcHBseSh0aGlzQXJnLCBhcmdzKTsKfQpmdW5jdGlvbiBiYXNlVGltZXMobiwgaXRlcmF0ZWUpIHsKICB2YXIgaW5kZXggPSAtMSwKICAgICAgcmVzdWx0ID0gQXJyYXkobik7CgogIHdoaWxlICgrK2luZGV4IDwgbikgewogICAgcmVzdWx0W2luZGV4XSA9IGl0ZXJhdGVlKGluZGV4KTsKICB9CiAgcmV0dXJuIHJlc3VsdDsKfQpmdW5jdGlvbiBiYXNlVW5hcnkoZnVuYykgewogIHJldHVybiBmdW5jdGlvbih2YWx1ZSkgewogICAgcmV0dXJuIGZ1bmModmFsdWUpOwogIH07Cn0KZnVuY3Rpb24gZ2V0VmFsdWUob2JqZWN0LCBrZXkpIHsKICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBvYmplY3Rba2V5XTsKfQpmdW5jdGlvbiBvdmVyQXJnKGZ1bmMsIHRyYW5zZm9ybSkgewogIHJldHVybiBmdW5jdGlvbihhcmcpIHsKICAgIHJldHVybiBmdW5jKHRyYW5zZm9ybShhcmcpKTsKICB9Owp9CmZ1bmN0aW9uIHNhZmVHZXQob2JqZWN0LCBrZXkpIHsKICByZXR1cm4ga2V5ID09ICdfX3Byb3RvX18nCiAgICA/IHVuZGVmaW5lZAogICAgOiBvYmplY3Rba2V5XTsKfQp2YXIgYXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZSwKICAgIGZ1bmNQcm90byA9IEZ1bmN0aW9uLnByb3RvdHlwZSwKICAgIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTsKdmFyIGNvcmVKc0RhdGEgPSByb290WydfX2NvcmUtanNfc2hhcmVkX18nXTsKdmFyIGZ1bmNUb1N0cmluZyA9IGZ1bmNQcm90by50b1N0cmluZzsKdmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7CnZhciBtYXNrU3JjS2V5ID0gKGZ1bmN0aW9uKCkgewogIHZhciB1aWQgPSAvW14uXSskLy5leGVjKGNvcmVKc0RhdGEgJiYgY29yZUpzRGF0YS5rZXlzICYmIGNvcmVKc0RhdGEua2V5cy5JRV9QUk9UTyB8fCAnJyk7CiAgcmV0dXJuIHVpZCA/ICgnU3ltYm9sKHNyYylfMS4nICsgdWlkKSA6ICcnOwp9KCkpOwp2YXIgbmF0aXZlT2JqZWN0VG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZzsKdmFyIG9iamVjdEN0b3JTdHJpbmcgPSBmdW5jVG9TdHJpbmcuY2FsbChPYmplY3QpOwp2YXIgcmVJc05hdGl2ZSA9IFJlZ0V4cCgnXicgKwogIGZ1bmNUb1N0cmluZy5jYWxsKGhhc093blByb3BlcnR5KS5yZXBsYWNlKHJlUmVnRXhwQ2hhciwgJ1xcJCYnKQogIC5yZXBsYWNlKC9oYXNPd25Qcm9wZXJ0eXwoZnVuY3Rpb24pLio/KD89XFxcKCl8IGZvciAuKz8oPz1cXFxdKS9nLCAnJDEuKj8nKSArICckJwopOwp2YXIgQnVmZmVyID0gbW9kdWxlRXhwb3J0cyA/IHJvb3QuQnVmZmVyIDogdW5kZWZpbmVkLAogICAgU3ltYm9sID0gcm9vdC5TeW1ib2wsCiAgICBVaW50OEFycmF5ID0gcm9vdC5VaW50OEFycmF5LAogICAgYWxsb2NVbnNhZmUgPSBCdWZmZXIgPyBCdWZmZXIuYWxsb2NVbnNhZmUgOiB1bmRlZmluZWQsCiAgICBnZXRQcm90b3R5cGUgPSBvdmVyQXJnKE9iamVjdC5nZXRQcm90b3R5cGVPZiwgT2JqZWN0KSwKICAgIG9iamVjdENyZWF0ZSA9IE9iamVjdC5jcmVhdGUsCiAgICBwcm9wZXJ0eUlzRW51bWVyYWJsZSA9IG9iamVjdFByb3RvLnByb3BlcnR5SXNFbnVtZXJhYmxlLAogICAgc3BsaWNlID0gYXJyYXlQcm90by5zcGxpY2UsCiAgICBzeW1Ub1N0cmluZ1RhZyA9IFN5bWJvbCA/IFN5bWJvbC50b1N0cmluZ1RhZyA6IHVuZGVmaW5lZDsKCnZhciBkZWZpbmVQcm9wZXJ0eSA9IChmdW5jdGlvbigpIHsKICB0cnkgewogICAgdmFyIGZ1bmMgPSBnZXROYXRpdmUoT2JqZWN0LCAnZGVmaW5lUHJvcGVydHknKTsKICAgIGZ1bmMoe30sICcnLCB7fSk7CiAgICByZXR1cm4gZnVuYzsKICB9IGNhdGNoIChlKSB7fQp9KCkpOwp2YXIgbmF0aXZlSXNCdWZmZXIgPSBCdWZmZXIgPyBCdWZmZXIuaXNCdWZmZXIgOiB1bmRlZmluZWQsCiAgICBuYXRpdmVNYXggPSBNYXRoLm1heCwKICAgIG5hdGl2ZU5vdyA9IERhdGUubm93Owp2YXIgTWFwID0gZ2V0TmF0aXZlKHJvb3QsICdNYXAnKSwKICAgIG5hdGl2ZUNyZWF0ZSA9IGdldE5hdGl2ZShPYmplY3QsICdjcmVhdGUnKTsKdmFyIGJhc2VDcmVhdGUgPSAoZnVuY3Rpb24oKSB7CiAgZnVuY3Rpb24gb2JqZWN0KCkge30KICByZXR1cm4gZnVuY3Rpb24ocHJvdG8pIHsKICAgIGlmICghaXNPYmplY3QocHJvdG8pKSB7CiAgICAgIHJldHVybiB7fTsKICAgIH0KICAgIGlmIChvYmplY3RDcmVhdGUpIHsKICAgICAgcmV0dXJuIG9iamVjdENyZWF0ZShwcm90byk7CiAgICB9CiAgICBvYmplY3QucHJvdG90eXBlID0gcHJvdG87CiAgICB2YXIgcmVzdWx0ID0gbmV3IG9iamVjdDsKICAgIG9iamVjdC5wcm90b3R5cGUgPSB1bmRlZmluZWQ7CiAgICByZXR1cm4gcmVzdWx0OwogIH07Cn0oKSk7CmZ1bmN0aW9uIEhhc2goZW50cmllcykgewogIHZhciBpbmRleCA9IC0xLAogICAgICBsZW5ndGggPSBlbnRyaWVzID09IG51bGwgPyAwIDogZW50cmllcy5sZW5ndGg7CgogIHRoaXMuY2xlYXIoKTsKICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkgewogICAgdmFyIGVudHJ5ID0gZW50cmllc1tpbmRleF07CiAgICB0aGlzLnNldChlbnRyeVswXSwgZW50cnlbMV0pOwogIH0KfQpmdW5jdGlvbiBoYXNoQ2xlYXIoKSB7CiAgdGhpcy5fX2RhdGFfXyA9IG5hdGl2ZUNyZWF0ZSA/IG5hdGl2ZUNyZWF0ZShudWxsKSA6IHt9OwogIHRoaXMuc2l6ZSA9IDA7Cn0KZnVuY3Rpb24gaGFzaERlbGV0ZShrZXkpIHsKICB2YXIgcmVzdWx0ID0gdGhpcy5oYXMoa2V5KSAmJiBkZWxldGUgdGhpcy5fX2RhdGFfX1trZXldOwogIHRoaXMuc2l6ZSAtPSByZXN1bHQgPyAxIDogMDsKICByZXR1cm4gcmVzdWx0Owp9CmZ1bmN0aW9uIGhhc2hHZXQoa2V5KSB7CiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fOwogIGlmIChuYXRpdmVDcmVhdGUpIHsKICAgIHZhciByZXN1bHQgPSBkYXRhW2tleV07CiAgICByZXR1cm4gcmVzdWx0ID09PSBIQVNIX1VOREVGSU5FRCA/IHVuZGVmaW5lZCA6IHJlc3VsdDsKICB9CiAgcmV0dXJuIGhhc093blByb3BlcnR5LmNhbGwoZGF0YSwga2V5KSA/IGRhdGFba2V5XSA6IHVuZGVmaW5lZDsKfQpmdW5jdGlvbiBoYXNoSGFzKGtleSkgewogIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXzsKICByZXR1cm4gbmF0aXZlQ3JlYXRlID8gKGRhdGFba2V5XSAhPT0gdW5kZWZpbmVkKSA6IGhhc093blByb3BlcnR5LmNhbGwoZGF0YSwga2V5KTsKfQpmdW5jdGlvbiBoYXNoU2V0KGtleSwgdmFsdWUpIHsKICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX187CiAgdGhpcy5zaXplICs9IHRoaXMuaGFzKGtleSkgPyAwIDogMTsKICBkYXRhW2tleV0gPSAobmF0aXZlQ3JlYXRlICYmIHZhbHVlID09PSB1bmRlZmluZWQpID8gSEFTSF9VTkRFRklORUQgOiB2YWx1ZTsKICByZXR1cm4gdGhpczsKfQpIYXNoLnByb3RvdHlwZS5jbGVhciA9IGhhc2hDbGVhcjsKSGFzaC5wcm90b3R5cGVbJ2RlbGV0ZSddID0gaGFzaERlbGV0ZTsKSGFzaC5wcm90b3R5cGUuZ2V0ID0gaGFzaEdldDsKSGFzaC5wcm90b3R5cGUuaGFzID0gaGFzaEhhczsKSGFzaC5wcm90b3R5cGUuc2V0ID0gaGFzaFNldDsKZnVuY3Rpb24gTGlzdENhY2hlKGVudHJpZXMpIHsKICB2YXIgaW5kZXggPSAtMSwKICAgICAgbGVuZ3RoID0gZW50cmllcyA9PSBudWxsID8gMCA6IGVudHJpZXMubGVuZ3RoOwoKICB0aGlzLmNsZWFyKCk7CiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHsKICAgIHZhciBlbnRyeSA9IGVudHJpZXNbaW5kZXhdOwogICAgdGhpcy5zZXQoZW50cnlbMF0sIGVudHJ5WzFdKTsKICB9Cn0KZnVuY3Rpb24gbGlzdENhY2hlQ2xlYXIoKSB7CiAgdGhpcy5fX2RhdGFfXyA9IFtdOwogIHRoaXMuc2l6ZSA9IDA7Cn0KZnVuY3Rpb24gbGlzdENhY2hlRGVsZXRlKGtleSkgewogIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXywKICAgICAgaW5kZXggPSBhc3NvY0luZGV4T2YoZGF0YSwga2V5KTsKCiAgaWYgKGluZGV4IDwgMCkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KICB2YXIgbGFzdEluZGV4ID0gZGF0YS5sZW5ndGggLSAxOwogIGlmIChpbmRleCA9PSBsYXN0SW5kZXgpIHsKICAgIGRhdGEucG9wKCk7CiAgfSBlbHNlIHsKICAgIHNwbGljZS5jYWxsKGRhdGEsIGluZGV4LCAxKTsKICB9CiAgLS10aGlzLnNpemU7CiAgcmV0dXJuIHRydWU7Cn0KZnVuY3Rpb24gbGlzdENhY2hlR2V0KGtleSkgewogIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXywKICAgICAgaW5kZXggPSBhc3NvY0luZGV4T2YoZGF0YSwga2V5KTsKCiAgcmV0dXJuIGluZGV4IDwgMCA/IHVuZGVmaW5lZCA6IGRhdGFbaW5kZXhdWzFdOwp9CmZ1bmN0aW9uIGxpc3RDYWNoZUhhcyhrZXkpIHsKICByZXR1cm4gYXNzb2NJbmRleE9mKHRoaXMuX19kYXRhX18sIGtleSkgPiAtMTsKfQpmdW5jdGlvbiBsaXN0Q2FjaGVTZXQoa2V5LCB2YWx1ZSkgewogIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXywKICAgICAgaW5kZXggPSBhc3NvY0luZGV4T2YoZGF0YSwga2V5KTsKCiAgaWYgKGluZGV4IDwgMCkgewogICAgKyt0aGlzLnNpemU7CiAgICBkYXRhLnB1c2goW2tleSwgdmFsdWVdKTsKICB9IGVsc2UgewogICAgZGF0YVtpbmRleF1bMV0gPSB2YWx1ZTsKICB9CiAgcmV0dXJuIHRoaXM7Cn0KTGlzdENhY2hlLnByb3RvdHlwZS5jbGVhciA9IGxpc3RDYWNoZUNsZWFyOwpMaXN0Q2FjaGUucHJvdG90eXBlWydkZWxldGUnXSA9IGxpc3RDYWNoZURlbGV0ZTsKTGlzdENhY2hlLnByb3RvdHlwZS5nZXQgPSBsaXN0Q2FjaGVHZXQ7Ckxpc3RDYWNoZS5wcm90b3R5cGUuaGFzID0gbGlzdENhY2hlSGFzOwpMaXN0Q2FjaGUucHJvdG90eXBlLnNldCA9IGxpc3RDYWNoZVNldDsKZnVuY3Rpb24gTWFwQ2FjaGUoZW50cmllcykgewogIHZhciBpbmRleCA9IC0xLAogICAgICBsZW5ndGggPSBlbnRyaWVzID09IG51bGwgPyAwIDogZW50cmllcy5sZW5ndGg7CgogIHRoaXMuY2xlYXIoKTsKICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkgewogICAgdmFyIGVudHJ5ID0gZW50cmllc1tpbmRleF07CiAgICB0aGlzLnNldChlbnRyeVswXSwgZW50cnlbMV0pOwogIH0KfQpmdW5jdGlvbiBtYXBDYWNoZUNsZWFyKCkgewogIHRoaXMuc2l6ZSA9IDA7CiAgdGhpcy5fX2RhdGFfXyA9IHsKICAgICdoYXNoJzogbmV3IEhhc2gsCiAgICAnbWFwJzogbmV3IChNYXAgfHwgTGlzdENhY2hlKSwKICAgICdzdHJpbmcnOiBuZXcgSGFzaAogIH07Cn0KZnVuY3Rpb24gbWFwQ2FjaGVEZWxldGUoa2V5KSB7CiAgdmFyIHJlc3VsdCA9IGdldE1hcERhdGEodGhpcywga2V5KVsnZGVsZXRlJ10oa2V5KTsKICB0aGlzLnNpemUgLT0gcmVzdWx0ID8gMSA6IDA7CiAgcmV0dXJuIHJlc3VsdDsKfQpmdW5jdGlvbiBtYXBDYWNoZUdldChrZXkpIHsKICByZXR1cm4gZ2V0TWFwRGF0YSh0aGlzLCBrZXkpLmdldChrZXkpOwp9CmZ1bmN0aW9uIG1hcENhY2hlSGFzKGtleSkgewogIHJldHVybiBnZXRNYXBEYXRhKHRoaXMsIGtleSkuaGFzKGtleSk7Cn0KZnVuY3Rpb24gbWFwQ2FjaGVTZXQoa2V5LCB2YWx1ZSkgewogIHZhciBkYXRhID0gZ2V0TWFwRGF0YSh0aGlzLCBrZXkpLAogICAgICBzaXplID0gZGF0YS5zaXplOwoKICBkYXRhLnNldChrZXksIHZhbHVlKTsKICB0aGlzLnNpemUgKz0gZGF0YS5zaXplID09IHNpemUgPyAwIDogMTsKICByZXR1cm4gdGhpczsKfQpNYXBDYWNoZS5wcm90b3R5cGUuY2xlYXIgPSBtYXBDYWNoZUNsZWFyOwpNYXBDYWNoZS5wcm90b3R5cGVbJ2RlbGV0ZSddID0gbWFwQ2FjaGVEZWxldGU7Ck1hcENhY2hlLnByb3RvdHlwZS5nZXQgPSBtYXBDYWNoZUdldDsKTWFwQ2FjaGUucHJvdG90eXBlLmhhcyA9IG1hcENhY2hlSGFzOwpNYXBDYWNoZS5wcm90b3R5cGUuc2V0ID0gbWFwQ2FjaGVTZXQ7CmZ1bmN0aW9uIFN0YWNrKGVudHJpZXMpIHsKICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18gPSBuZXcgTGlzdENhY2hlKGVudHJpZXMpOwogIHRoaXMuc2l6ZSA9IGRhdGEuc2l6ZTsKfQpmdW5jdGlvbiBzdGFja0NsZWFyKCkgewogIHRoaXMuX19kYXRhX18gPSBuZXcgTGlzdENhY2hlOwogIHRoaXMuc2l6ZSA9IDA7Cn0KZnVuY3Rpb24gc3RhY2tEZWxldGUoa2V5KSB7CiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fLAogICAgICByZXN1bHQgPSBkYXRhWydkZWxldGUnXShrZXkpOwoKICB0aGlzLnNpemUgPSBkYXRhLnNpemU7CiAgcmV0dXJuIHJlc3VsdDsKfQpmdW5jdGlvbiBzdGFja0dldChrZXkpIHsKICByZXR1cm4gdGhpcy5fX2RhdGFfXy5nZXQoa2V5KTsKfQpmdW5jdGlvbiBzdGFja0hhcyhrZXkpIHsKICByZXR1cm4gdGhpcy5fX2RhdGFfXy5oYXMoa2V5KTsKfQpmdW5jdGlvbiBzdGFja1NldChrZXksIHZhbHVlKSB7CiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fOwogIGlmIChkYXRhIGluc3RhbmNlb2YgTGlzdENhY2hlKSB7CiAgICB2YXIgcGFpcnMgPSBkYXRhLl9fZGF0YV9fOwogICAgaWYgKCFNYXAgfHwgKHBhaXJzLmxlbmd0aCA8IExBUkdFX0FSUkFZX1NJWkUgLSAxKSkgewogICAgICBwYWlycy5wdXNoKFtrZXksIHZhbHVlXSk7CiAgICAgIHRoaXMuc2l6ZSA9ICsrZGF0YS5zaXplOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIGRhdGEgPSB0aGlzLl9fZGF0YV9fID0gbmV3IE1hcENhY2hlKHBhaXJzKTsKICB9CiAgZGF0YS5zZXQoa2V5LCB2YWx1ZSk7CiAgdGhpcy5zaXplID0gZGF0YS5zaXplOwogIHJldHVybiB0aGlzOwp9ClN0YWNrLnByb3RvdHlwZS5jbGVhciA9IHN0YWNrQ2xlYXI7ClN0YWNrLnByb3RvdHlwZVsnZGVsZXRlJ10gPSBzdGFja0RlbGV0ZTsKU3RhY2sucHJvdG90eXBlLmdldCA9IHN0YWNrR2V0OwpTdGFjay5wcm90b3R5cGUuaGFzID0gc3RhY2tIYXM7ClN0YWNrLnByb3RvdHlwZS5zZXQgPSBzdGFja1NldDsKZnVuY3Rpb24gYXJyYXlMaWtlS2V5cyh2YWx1ZSwgaW5oZXJpdGVkKSB7CiAgdmFyIGlzQXJyID0gaXNBcnJheSh2YWx1ZSksCiAgICAgIGlzQXJnID0gIWlzQXJyICYmIGlzQXJndW1lbnRzKHZhbHVlKSwKICAgICAgaXNCdWZmID0gIWlzQXJyICYmICFpc0FyZyAmJiBpc0J1ZmZlcih2YWx1ZSksCiAgICAgIGlzVHlwZSA9ICFpc0FyciAmJiAhaXNBcmcgJiYgIWlzQnVmZiAmJiBpc1R5cGVkQXJyYXkodmFsdWUpLAogICAgICBza2lwSW5kZXhlcyA9IGlzQXJyIHx8IGlzQXJnIHx8IGlzQnVmZiB8fCBpc1R5cGUsCiAgICAgIHJlc3VsdCA9IHNraXBJbmRleGVzID8gYmFzZVRpbWVzKHZhbHVlLmxlbmd0aCwgU3RyaW5nKSA6IFtdLAogICAgICBsZW5ndGggPSByZXN1bHQubGVuZ3RoOwoKICBmb3IgKHZhciBrZXkgaW4gdmFsdWUpIHsKICAgIGlmICgoaW5oZXJpdGVkIHx8IGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsIGtleSkpICYmCiAgICAgICAgIShza2lwSW5kZXhlcyAmJiAoCiAgICAgICAgICAga2V5ID09ICdsZW5ndGgnIHx8CiAgICAgICAgICAgKGlzQnVmZiAmJiAoa2V5ID09ICdvZmZzZXQnIHx8IGtleSA9PSAncGFyZW50JykpIHx8CiAgICAgICAgICAgKGlzVHlwZSAmJiAoa2V5ID09ICdidWZmZXInIHx8IGtleSA9PSAnYnl0ZUxlbmd0aCcgfHwga2V5ID09ICdieXRlT2Zmc2V0JykpIHx8CiAgICAgICAgICAgaXNJbmRleChrZXksIGxlbmd0aCkKICAgICAgICApKSkgewogICAgICByZXN1bHQucHVzaChrZXkpOwogICAgfQogIH0KICByZXR1cm4gcmVzdWx0Owp9CmZ1bmN0aW9uIGFzc2lnbk1lcmdlVmFsdWUob2JqZWN0LCBrZXksIHZhbHVlKSB7CiAgaWYgKCh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmICFlcShvYmplY3Rba2V5XSwgdmFsdWUpKSB8fAogICAgICAodmFsdWUgPT09IHVuZGVmaW5lZCAmJiAhKGtleSBpbiBvYmplY3QpKSkgewogICAgYmFzZUFzc2lnblZhbHVlKG9iamVjdCwga2V5LCB2YWx1ZSk7CiAgfQp9CmZ1bmN0aW9uIGFzc2lnblZhbHVlKG9iamVjdCwga2V5LCB2YWx1ZSkgewogIHZhciBvYmpWYWx1ZSA9IG9iamVjdFtrZXldOwogIGlmICghKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpICYmIGVxKG9ialZhbHVlLCB2YWx1ZSkpIHx8CiAgICAgICh2YWx1ZSA9PT0gdW5kZWZpbmVkICYmICEoa2V5IGluIG9iamVjdCkpKSB7CiAgICBiYXNlQXNzaWduVmFsdWUob2JqZWN0LCBrZXksIHZhbHVlKTsKICB9Cn0KZnVuY3Rpb24gYXNzb2NJbmRleE9mKGFycmF5LCBrZXkpIHsKICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoOwogIHdoaWxlIChsZW5ndGgtLSkgewogICAgaWYgKGVxKGFycmF5W2xlbmd0aF1bMF0sIGtleSkpIHsKICAgICAgcmV0dXJuIGxlbmd0aDsKICAgIH0KICB9CiAgcmV0dXJuIC0xOwp9CmZ1bmN0aW9uIGJhc2VBc3NpZ25WYWx1ZShvYmplY3QsIGtleSwgdmFsdWUpIHsKICBpZiAoa2V5ID09ICdfX3Byb3RvX18nICYmIGRlZmluZVByb3BlcnR5KSB7CiAgICBkZWZpbmVQcm9wZXJ0eShvYmplY3QsIGtleSwgewogICAgICAnY29uZmlndXJhYmxlJzogdHJ1ZSwKICAgICAgJ2VudW1lcmFibGUnOiB0cnVlLAogICAgICAndmFsdWUnOiB2YWx1ZSwKICAgICAgJ3dyaXRhYmxlJzogdHJ1ZQogICAgfSk7CiAgfSBlbHNlIHsKICAgIG9iamVjdFtrZXldID0gdmFsdWU7CiAgfQp9CnZhciBiYXNlRm9yID0gY3JlYXRlQmFzZUZvcigpOwpmdW5jdGlvbiBiYXNlR2V0VGFnKHZhbHVlKSB7CiAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgIHJldHVybiB2YWx1ZSA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkVGFnIDogbnVsbFRhZzsKICB9CiAgcmV0dXJuIChzeW1Ub1N0cmluZ1RhZyAmJiBzeW1Ub1N0cmluZ1RhZyBpbiBPYmplY3QodmFsdWUpKQogICAgPyBnZXRSYXdUYWcodmFsdWUpCiAgICA6IG9iamVjdFRvU3RyaW5nKHZhbHVlKTsKfQpmdW5jdGlvbiBiYXNlSXNBcmd1bWVudHModmFsdWUpIHsKICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBiYXNlR2V0VGFnKHZhbHVlKSA9PSBhcmdzVGFnOwp9CmZ1bmN0aW9uIGJhc2VJc05hdGl2ZSh2YWx1ZSkgewogIGlmICghaXNPYmplY3QodmFsdWUpIHx8IGlzTWFza2VkKHZhbHVlKSkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KICB2YXIgcGF0dGVybiA9IGlzRnVuY3Rpb24odmFsdWUpID8gcmVJc05hdGl2ZSA6IHJlSXNIb3N0Q3RvcjsKICByZXR1cm4gcGF0dGVybi50ZXN0KHRvU291cmNlKHZhbHVlKSk7Cn0KZnVuY3Rpb24gYmFzZUlzVHlwZWRBcnJheSh2YWx1ZSkgewogIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmCiAgICBpc0xlbmd0aCh2YWx1ZS5sZW5ndGgpICYmICEhdHlwZWRBcnJheVRhZ3NbYmFzZUdldFRhZyh2YWx1ZSldOwp9CmZ1bmN0aW9uIGJhc2VLZXlzSW4ob2JqZWN0KSB7CiAgaWYgKCFpc09iamVjdChvYmplY3QpKSB7CiAgICByZXR1cm4gbmF0aXZlS2V5c0luKG9iamVjdCk7CiAgfQogIHZhciBpc1Byb3RvID0gaXNQcm90b3R5cGUob2JqZWN0KSwKICAgICAgcmVzdWx0ID0gW107CgogIGZvciAodmFyIGtleSBpbiBvYmplY3QpIHsKICAgIGlmICghKGtleSA9PSAnY29uc3RydWN0b3InICYmIChpc1Byb3RvIHx8ICFoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSkpKSB7CiAgICAgIHJlc3VsdC5wdXNoKGtleSk7CiAgICB9CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KZnVuY3Rpb24gYmFzZU1lcmdlKG9iamVjdCwgc291cmNlLCBzcmNJbmRleCwgY3VzdG9taXplciwgc3RhY2spIHsKICBpZiAob2JqZWN0ID09PSBzb3VyY2UpIHsKICAgIHJldHVybjsKICB9CiAgYmFzZUZvcihzb3VyY2UsIGZ1bmN0aW9uKHNyY1ZhbHVlLCBrZXkpIHsKICAgIGlmIChpc09iamVjdChzcmNWYWx1ZSkpIHsKICAgICAgc3RhY2sgfHwgKHN0YWNrID0gbmV3IFN0YWNrKTsKICAgICAgYmFzZU1lcmdlRGVlcChvYmplY3QsIHNvdXJjZSwga2V5LCBzcmNJbmRleCwgYmFzZU1lcmdlLCBjdXN0b21pemVyLCBzdGFjayk7CiAgICB9CiAgICBlbHNlIHsKICAgICAgdmFyIG5ld1ZhbHVlID0gY3VzdG9taXplcgogICAgICAgID8gY3VzdG9taXplcihzYWZlR2V0KG9iamVjdCwga2V5KSwgc3JjVmFsdWUsIChrZXkgKyAnJyksIG9iamVjdCwgc291cmNlLCBzdGFjaykKICAgICAgICA6IHVuZGVmaW5lZDsKCiAgICAgIGlmIChuZXdWYWx1ZSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgbmV3VmFsdWUgPSBzcmNWYWx1ZTsKICAgICAgfQogICAgICBhc3NpZ25NZXJnZVZhbHVlKG9iamVjdCwga2V5LCBuZXdWYWx1ZSk7CiAgICB9CiAgfSwga2V5c0luKTsKfQpmdW5jdGlvbiBiYXNlTWVyZ2VEZWVwKG9iamVjdCwgc291cmNlLCBrZXksIHNyY0luZGV4LCBtZXJnZUZ1bmMsIGN1c3RvbWl6ZXIsIHN0YWNrKSB7CiAgdmFyIG9ialZhbHVlID0gc2FmZUdldChvYmplY3QsIGtleSksCiAgICAgIHNyY1ZhbHVlID0gc2FmZUdldChzb3VyY2UsIGtleSksCiAgICAgIHN0YWNrZWQgPSBzdGFjay5nZXQoc3JjVmFsdWUpOwoKICBpZiAoc3RhY2tlZCkgewogICAgYXNzaWduTWVyZ2VWYWx1ZShvYmplY3QsIGtleSwgc3RhY2tlZCk7CiAgICByZXR1cm47CiAgfQogIHZhciBuZXdWYWx1ZSA9IGN1c3RvbWl6ZXIKICAgID8gY3VzdG9taXplcihvYmpWYWx1ZSwgc3JjVmFsdWUsIChrZXkgKyAnJyksIG9iamVjdCwgc291cmNlLCBzdGFjaykKICAgIDogdW5kZWZpbmVkOwoKICB2YXIgaXNDb21tb24gPSBuZXdWYWx1ZSA9PT0gdW5kZWZpbmVkOwoKICBpZiAoaXNDb21tb24pIHsKICAgIHZhciBpc0FyciA9IGlzQXJyYXkoc3JjVmFsdWUpLAogICAgICAgIGlzQnVmZiA9ICFpc0FyciAmJiBpc0J1ZmZlcihzcmNWYWx1ZSksCiAgICAgICAgaXNUeXBlZCA9ICFpc0FyciAmJiAhaXNCdWZmICYmIGlzVHlwZWRBcnJheShzcmNWYWx1ZSk7CgogICAgbmV3VmFsdWUgPSBzcmNWYWx1ZTsKICAgIGlmIChpc0FyciB8fCBpc0J1ZmYgfHwgaXNUeXBlZCkgewogICAgICBpZiAoaXNBcnJheShvYmpWYWx1ZSkpIHsKICAgICAgICBuZXdWYWx1ZSA9IG9ialZhbHVlOwogICAgICB9CiAgICAgIGVsc2UgaWYgKGlzQXJyYXlMaWtlT2JqZWN0KG9ialZhbHVlKSkgewogICAgICAgIG5ld1ZhbHVlID0gY29weUFycmF5KG9ialZhbHVlKTsKICAgICAgfQogICAgICBlbHNlIGlmIChpc0J1ZmYpIHsKICAgICAgICBpc0NvbW1vbiA9IGZhbHNlOwogICAgICAgIG5ld1ZhbHVlID0gY2xvbmVCdWZmZXIoc3JjVmFsdWUsIHRydWUpOwogICAgICB9CiAgICAgIGVsc2UgaWYgKGlzVHlwZWQpIHsKICAgICAgICBpc0NvbW1vbiA9IGZhbHNlOwogICAgICAgIG5ld1ZhbHVlID0gY2xvbmVUeXBlZEFycmF5KHNyY1ZhbHVlLCB0cnVlKTsKICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICBuZXdWYWx1ZSA9IFtdOwogICAgICB9CiAgICB9CiAgICBlbHNlIGlmIChpc1BsYWluT2JqZWN0KHNyY1ZhbHVlKSB8fCBpc0FyZ3VtZW50cyhzcmNWYWx1ZSkpIHsKICAgICAgbmV3VmFsdWUgPSBvYmpWYWx1ZTsKICAgICAgaWYgKGlzQXJndW1lbnRzKG9ialZhbHVlKSkgewogICAgICAgIG5ld1ZhbHVlID0gdG9QbGFpbk9iamVjdChvYmpWYWx1ZSk7CiAgICAgIH0KICAgICAgZWxzZSBpZiAoIWlzT2JqZWN0KG9ialZhbHVlKSB8fCAoc3JjSW5kZXggJiYgaXNGdW5jdGlvbihvYmpWYWx1ZSkpKSB7CiAgICAgICAgbmV3VmFsdWUgPSBpbml0Q2xvbmVPYmplY3Qoc3JjVmFsdWUpOwogICAgICB9CiAgICB9CiAgICBlbHNlIHsKICAgICAgaXNDb21tb24gPSBmYWxzZTsKICAgIH0KICB9CiAgaWYgKGlzQ29tbW9uKSB7CiAgICBzdGFjay5zZXQoc3JjVmFsdWUsIG5ld1ZhbHVlKTsKICAgIG1lcmdlRnVuYyhuZXdWYWx1ZSwgc3JjVmFsdWUsIHNyY0luZGV4LCBjdXN0b21pemVyLCBzdGFjayk7CiAgICBzdGFja1snZGVsZXRlJ10oc3JjVmFsdWUpOwogIH0KICBhc3NpZ25NZXJnZVZhbHVlKG9iamVjdCwga2V5LCBuZXdWYWx1ZSk7Cn0KZnVuY3Rpb24gYmFzZVJlc3QoZnVuYywgc3RhcnQpIHsKICByZXR1cm4gc2V0VG9TdHJpbmcob3ZlclJlc3QoZnVuYywgc3RhcnQsIGlkZW50aXR5KSwgZnVuYyArICcnKTsKfQp2YXIgYmFzZVNldFRvU3RyaW5nID0gIWRlZmluZVByb3BlcnR5ID8gaWRlbnRpdHkgOiBmdW5jdGlvbihmdW5jLCBzdHJpbmcpIHsKICByZXR1cm4gZGVmaW5lUHJvcGVydHkoZnVuYywgJ3RvU3RyaW5nJywgewogICAgJ2NvbmZpZ3VyYWJsZSc6IHRydWUsCiAgICAnZW51bWVyYWJsZSc6IGZhbHNlLAogICAgJ3ZhbHVlJzogY29uc3RhbnQoc3RyaW5nKSwKICAgICd3cml0YWJsZSc6IHRydWUKICB9KTsKfTsKZnVuY3Rpb24gY2xvbmVCdWZmZXIoYnVmZmVyLCBpc0RlZXApIHsKICBpZiAoaXNEZWVwKSB7CiAgICByZXR1cm4gYnVmZmVyLnNsaWNlKCk7CiAgfQogIHZhciBsZW5ndGggPSBidWZmZXIubGVuZ3RoLAogICAgICByZXN1bHQgPSBhbGxvY1Vuc2FmZSA/IGFsbG9jVW5zYWZlKGxlbmd0aCkgOiBuZXcgYnVmZmVyLmNvbnN0cnVjdG9yKGxlbmd0aCk7CgogIGJ1ZmZlci5jb3B5KHJlc3VsdCk7CiAgcmV0dXJuIHJlc3VsdDsKfQpmdW5jdGlvbiBjbG9uZUFycmF5QnVmZmVyKGFycmF5QnVmZmVyKSB7CiAgdmFyIHJlc3VsdCA9IG5ldyBhcnJheUJ1ZmZlci5jb25zdHJ1Y3RvcihhcnJheUJ1ZmZlci5ieXRlTGVuZ3RoKTsKICBuZXcgVWludDhBcnJheShyZXN1bHQpLnNldChuZXcgVWludDhBcnJheShhcnJheUJ1ZmZlcikpOwogIHJldHVybiByZXN1bHQ7Cn0KZnVuY3Rpb24gY2xvbmVUeXBlZEFycmF5KHR5cGVkQXJyYXksIGlzRGVlcCkgewogIHZhciBidWZmZXIgPSBpc0RlZXAgPyBjbG9uZUFycmF5QnVmZmVyKHR5cGVkQXJyYXkuYnVmZmVyKSA6IHR5cGVkQXJyYXkuYnVmZmVyOwogIHJldHVybiBuZXcgdHlwZWRBcnJheS5jb25zdHJ1Y3RvcihidWZmZXIsIHR5cGVkQXJyYXkuYnl0ZU9mZnNldCwgdHlwZWRBcnJheS5sZW5ndGgpOwp9CmZ1bmN0aW9uIGNvcHlBcnJheShzb3VyY2UsIGFycmF5KSB7CiAgdmFyIGluZGV4ID0gLTEsCiAgICAgIGxlbmd0aCA9IHNvdXJjZS5sZW5ndGg7CgogIGFycmF5IHx8IChhcnJheSA9IEFycmF5KGxlbmd0aCkpOwogIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7CiAgICBhcnJheVtpbmRleF0gPSBzb3VyY2VbaW5kZXhdOwogIH0KICByZXR1cm4gYXJyYXk7Cn0KZnVuY3Rpb24gY29weU9iamVjdChzb3VyY2UsIHByb3BzLCBvYmplY3QsIGN1c3RvbWl6ZXIpIHsKICB2YXIgaXNOZXcgPSAhb2JqZWN0OwogIG9iamVjdCB8fCAob2JqZWN0ID0ge30pOwoKICB2YXIgaW5kZXggPSAtMSwKICAgICAgbGVuZ3RoID0gcHJvcHMubGVuZ3RoOwoKICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkgewogICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTsKCiAgICB2YXIgbmV3VmFsdWUgPSBjdXN0b21pemVyCiAgICAgID8gY3VzdG9taXplcihvYmplY3Rba2V5XSwgc291cmNlW2tleV0sIGtleSwgb2JqZWN0LCBzb3VyY2UpCiAgICAgIDogdW5kZWZpbmVkOwoKICAgIGlmIChuZXdWYWx1ZSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgIG5ld1ZhbHVlID0gc291cmNlW2tleV07CiAgICB9CiAgICBpZiAoaXNOZXcpIHsKICAgICAgYmFzZUFzc2lnblZhbHVlKG9iamVjdCwga2V5LCBuZXdWYWx1ZSk7CiAgICB9IGVsc2UgewogICAgICBhc3NpZ25WYWx1ZShvYmplY3QsIGtleSwgbmV3VmFsdWUpOwogICAgfQogIH0KICByZXR1cm4gb2JqZWN0Owp9CmZ1bmN0aW9uIGNyZWF0ZUFzc2lnbmVyKGFzc2lnbmVyKSB7CiAgcmV0dXJuIGJhc2VSZXN0KGZ1bmN0aW9uKG9iamVjdCwgc291cmNlcykgewogICAgdmFyIGluZGV4ID0gLTEsCiAgICAgICAgbGVuZ3RoID0gc291cmNlcy5sZW5ndGgsCiAgICAgICAgY3VzdG9taXplciA9IGxlbmd0aCA+IDEgPyBzb3VyY2VzW2xlbmd0aCAtIDFdIDogdW5kZWZpbmVkLAogICAgICAgIGd1YXJkID0gbGVuZ3RoID4gMiA/IHNvdXJjZXNbMl0gOiB1bmRlZmluZWQ7CgogICAgY3VzdG9taXplciA9IChhc3NpZ25lci5sZW5ndGggPiAzICYmIHR5cGVvZiBjdXN0b21pemVyID09ICdmdW5jdGlvbicpCiAgICAgID8gKGxlbmd0aC0tLCBjdXN0b21pemVyKQogICAgICA6IHVuZGVmaW5lZDsKCiAgICBpZiAoZ3VhcmQgJiYgaXNJdGVyYXRlZUNhbGwoc291cmNlc1swXSwgc291cmNlc1sxXSwgZ3VhcmQpKSB7CiAgICAgIGN1c3RvbWl6ZXIgPSBsZW5ndGggPCAzID8gdW5kZWZpbmVkIDogY3VzdG9taXplcjsKICAgICAgbGVuZ3RoID0gMTsKICAgIH0KICAgIG9iamVjdCA9IE9iamVjdChvYmplY3QpOwogICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHsKICAgICAgdmFyIHNvdXJjZSA9IHNvdXJjZXNbaW5kZXhdOwogICAgICBpZiAoc291cmNlKSB7CiAgICAgICAgYXNzaWduZXIob2JqZWN0LCBzb3VyY2UsIGluZGV4LCBjdXN0b21pemVyKTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIG9iamVjdDsKICB9KTsKfQpmdW5jdGlvbiBjcmVhdGVCYXNlRm9yKGZyb21SaWdodCkgewogIHJldHVybiBmdW5jdGlvbihvYmplY3QsIGl0ZXJhdGVlLCBrZXlzRnVuYykgewogICAgdmFyIGluZGV4ID0gLTEsCiAgICAgICAgaXRlcmFibGUgPSBPYmplY3Qob2JqZWN0KSwKICAgICAgICBwcm9wcyA9IGtleXNGdW5jKG9iamVjdCksCiAgICAgICAgbGVuZ3RoID0gcHJvcHMubGVuZ3RoOwoKICAgIHdoaWxlIChsZW5ndGgtLSkgewogICAgICB2YXIga2V5ID0gcHJvcHNbZnJvbVJpZ2h0ID8gbGVuZ3RoIDogKytpbmRleF07CiAgICAgIGlmIChpdGVyYXRlZShpdGVyYWJsZVtrZXldLCBrZXksIGl0ZXJhYmxlKSA9PT0gZmFsc2UpIHsKICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogICAgcmV0dXJuIG9iamVjdDsKICB9Owp9CmZ1bmN0aW9uIGdldE1hcERhdGEobWFwLCBrZXkpIHsKICB2YXIgZGF0YSA9IG1hcC5fX2RhdGFfXzsKICByZXR1cm4gaXNLZXlhYmxlKGtleSkKICAgID8gZGF0YVt0eXBlb2Yga2V5ID09ICdzdHJpbmcnID8gJ3N0cmluZycgOiAnaGFzaCddCiAgICA6IGRhdGEubWFwOwp9CmZ1bmN0aW9uIGdldE5hdGl2ZShvYmplY3QsIGtleSkgewogIHZhciB2YWx1ZSA9IGdldFZhbHVlKG9iamVjdCwga2V5KTsKICByZXR1cm4gYmFzZUlzTmF0aXZlKHZhbHVlKSA/IHZhbHVlIDogdW5kZWZpbmVkOwp9CmZ1bmN0aW9uIGdldFJhd1RhZyh2YWx1ZSkgewogIHZhciBpc093biA9IGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsIHN5bVRvU3RyaW5nVGFnKSwKICAgICAgdGFnID0gdmFsdWVbc3ltVG9TdHJpbmdUYWddOwoKICB0cnkgewogICAgdmFsdWVbc3ltVG9TdHJpbmdUYWddID0gdW5kZWZpbmVkOwogICAgdmFyIHVubWFza2VkID0gdHJ1ZTsKICB9IGNhdGNoIChlKSB7fQoKICB2YXIgcmVzdWx0ID0gbmF0aXZlT2JqZWN0VG9TdHJpbmcuY2FsbCh2YWx1ZSk7CiAgaWYgKHVubWFza2VkKSB7CiAgICBpZiAoaXNPd24pIHsKICAgICAgdmFsdWVbc3ltVG9TdHJpbmdUYWddID0gdGFnOwogICAgfSBlbHNlIHsKICAgICAgZGVsZXRlIHZhbHVlW3N5bVRvU3RyaW5nVGFnXTsKICAgIH0KICB9CiAgcmV0dXJuIHJlc3VsdDsKfQpmdW5jdGlvbiBpbml0Q2xvbmVPYmplY3Qob2JqZWN0KSB7CiAgcmV0dXJuICh0eXBlb2Ygb2JqZWN0LmNvbnN0cnVjdG9yID09ICdmdW5jdGlvbicgJiYgIWlzUHJvdG90eXBlKG9iamVjdCkpCiAgICA/IGJhc2VDcmVhdGUoZ2V0UHJvdG90eXBlKG9iamVjdCkpCiAgICA6IHt9Owp9CmZ1bmN0aW9uIGlzSW5kZXgodmFsdWUsIGxlbmd0aCkgewogIHZhciB0eXBlID0gdHlwZW9mIHZhbHVlOwogIGxlbmd0aCA9IGxlbmd0aCA9PSBudWxsID8gTUFYX1NBRkVfSU5URUdFUiA6IGxlbmd0aDsKCiAgcmV0dXJuICEhbGVuZ3RoICYmCiAgICAodHlwZSA9PSAnbnVtYmVyJyB8fAogICAgICAodHlwZSAhPSAnc3ltYm9sJyAmJiByZUlzVWludC50ZXN0KHZhbHVlKSkpICYmCiAgICAgICAgKHZhbHVlID4gLTEgJiYgdmFsdWUgJSAxID09IDAgJiYgdmFsdWUgPCBsZW5ndGgpOwp9CmZ1bmN0aW9uIGlzSXRlcmF0ZWVDYWxsKHZhbHVlLCBpbmRleCwgb2JqZWN0KSB7CiAgaWYgKCFpc09iamVjdChvYmplY3QpKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQogIHZhciB0eXBlID0gdHlwZW9mIGluZGV4OwogIGlmICh0eXBlID09ICdudW1iZXInCiAgICAgICAgPyAoaXNBcnJheUxpa2Uob2JqZWN0KSAmJiBpc0luZGV4KGluZGV4LCBvYmplY3QubGVuZ3RoKSkKICAgICAgICA6ICh0eXBlID09ICdzdHJpbmcnICYmIGluZGV4IGluIG9iamVjdCkKICAgICAgKSB7CiAgICByZXR1cm4gZXEob2JqZWN0W2luZGV4XSwgdmFsdWUpOwogIH0KICByZXR1cm4gZmFsc2U7Cn0KZnVuY3Rpb24gaXNLZXlhYmxlKHZhbHVlKSB7CiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7CiAgcmV0dXJuICh0eXBlID09ICdzdHJpbmcnIHx8IHR5cGUgPT0gJ251bWJlcicgfHwgdHlwZSA9PSAnc3ltYm9sJyB8fCB0eXBlID09ICdib29sZWFuJykKICAgID8gKHZhbHVlICE9PSAnX19wcm90b19fJykKICAgIDogKHZhbHVlID09PSBudWxsKTsKfQpmdW5jdGlvbiBpc01hc2tlZChmdW5jKSB7CiAgcmV0dXJuICEhbWFza1NyY0tleSAmJiAobWFza1NyY0tleSBpbiBmdW5jKTsKfQpmdW5jdGlvbiBpc1Byb3RvdHlwZSh2YWx1ZSkgewogIHZhciBDdG9yID0gdmFsdWUgJiYgdmFsdWUuY29uc3RydWN0b3IsCiAgICAgIHByb3RvID0gKHR5cGVvZiBDdG9yID09ICdmdW5jdGlvbicgJiYgQ3Rvci5wcm90b3R5cGUpIHx8IG9iamVjdFByb3RvOwoKICByZXR1cm4gdmFsdWUgPT09IHByb3RvOwp9CmZ1bmN0aW9uIG5hdGl2ZUtleXNJbihvYmplY3QpIHsKICB2YXIgcmVzdWx0ID0gW107CiAgaWYgKG9iamVjdCAhPSBudWxsKSB7CiAgICBmb3IgKHZhciBrZXkgaW4gT2JqZWN0KG9iamVjdCkpIHsKICAgICAgcmVzdWx0LnB1c2goa2V5KTsKICAgIH0KICB9CiAgcmV0dXJuIHJlc3VsdDsKfQpmdW5jdGlvbiBvYmplY3RUb1N0cmluZyh2YWx1ZSkgewogIHJldHVybiBuYXRpdmVPYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKTsKfQpmdW5jdGlvbiBvdmVyUmVzdChmdW5jLCBzdGFydCwgdHJhbnNmb3JtKSB7CiAgc3RhcnQgPSBuYXRpdmVNYXgoc3RhcnQgPT09IHVuZGVmaW5lZCA/IChmdW5jLmxlbmd0aCAtIDEpIDogc3RhcnQsIDApOwogIHJldHVybiBmdW5jdGlvbigpIHsKICAgIHZhciBhcmdzID0gYXJndW1lbnRzLAogICAgICAgIGluZGV4ID0gLTEsCiAgICAgICAgbGVuZ3RoID0gbmF0aXZlTWF4KGFyZ3MubGVuZ3RoIC0gc3RhcnQsIDApLAogICAgICAgIGFycmF5ID0gQXJyYXkobGVuZ3RoKTsKCiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkgewogICAgICBhcnJheVtpbmRleF0gPSBhcmdzW3N0YXJ0ICsgaW5kZXhdOwogICAgfQogICAgaW5kZXggPSAtMTsKICAgIHZhciBvdGhlckFyZ3MgPSBBcnJheShzdGFydCArIDEpOwogICAgd2hpbGUgKCsraW5kZXggPCBzdGFydCkgewogICAgICBvdGhlckFyZ3NbaW5kZXhdID0gYXJnc1tpbmRleF07CiAgICB9CiAgICBvdGhlckFyZ3Nbc3RhcnRdID0gdHJhbnNmb3JtKGFycmF5KTsKICAgIHJldHVybiBhcHBseShmdW5jLCB0aGlzLCBvdGhlckFyZ3MpOwogIH07Cn0KdmFyIHNldFRvU3RyaW5nID0gc2hvcnRPdXQoYmFzZVNldFRvU3RyaW5nKTsKZnVuY3Rpb24gc2hvcnRPdXQoZnVuYykgewogIHZhciBjb3VudCA9IDAsCiAgICAgIGxhc3RDYWxsZWQgPSAwOwoKICByZXR1cm4gZnVuY3Rpb24oKSB7CiAgICB2YXIgc3RhbXAgPSBuYXRpdmVOb3coKSwKICAgICAgICByZW1haW5pbmcgPSBIT1RfU1BBTiAtIChzdGFtcCAtIGxhc3RDYWxsZWQpOwoKICAgIGxhc3RDYWxsZWQgPSBzdGFtcDsKICAgIGlmIChyZW1haW5pbmcgPiAwKSB7CiAgICAgIGlmICgrK2NvdW50ID49IEhPVF9DT1VOVCkgewogICAgICAgIHJldHVybiBhcmd1bWVudHNbMF07CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIGNvdW50ID0gMDsKICAgIH0KICAgIHJldHVybiBmdW5jLmFwcGx5KHVuZGVmaW5lZCwgYXJndW1lbnRzKTsKICB9Owp9CmZ1bmN0aW9uIHRvU291cmNlKGZ1bmMpIHsKICBpZiAoZnVuYyAhPSBudWxsKSB7CiAgICB0cnkgewogICAgICByZXR1cm4gZnVuY1RvU3RyaW5nLmNhbGwoZnVuYyk7CiAgICB9IGNhdGNoIChlKSB7fQogICAgdHJ5IHsKICAgICAgcmV0dXJuIChmdW5jICsgJycpOwogICAgfSBjYXRjaCAoZSkge30KICB9CiAgcmV0dXJuICcnOwp9CmZ1bmN0aW9uIGVxKHZhbHVlLCBvdGhlcikgewogIHJldHVybiB2YWx1ZSA9PT0gb3RoZXIgfHwgKHZhbHVlICE9PSB2YWx1ZSAmJiBvdGhlciAhPT0gb3RoZXIpOwp9CnZhciBpc0FyZ3VtZW50cyA9IGJhc2VJc0FyZ3VtZW50cyhmdW5jdGlvbigpIHsgcmV0dXJuIGFyZ3VtZW50czsgfSgpKSA/IGJhc2VJc0FyZ3VtZW50cyA6IGZ1bmN0aW9uKHZhbHVlKSB7CiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgJ2NhbGxlZScpICYmCiAgICAhcHJvcGVydHlJc0VudW1lcmFibGUuY2FsbCh2YWx1ZSwgJ2NhbGxlZScpOwp9Owp2YXIgaXNBcnJheSA9IEFycmF5LmlzQXJyYXk7CmZ1bmN0aW9uIGlzQXJyYXlMaWtlKHZhbHVlKSB7CiAgcmV0dXJuIHZhbHVlICE9IG51bGwgJiYgaXNMZW5ndGgodmFsdWUubGVuZ3RoKSAmJiAhaXNGdW5jdGlvbih2YWx1ZSk7Cn0KZnVuY3Rpb24gaXNBcnJheUxpa2VPYmplY3QodmFsdWUpIHsKICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBpc0FycmF5TGlrZSh2YWx1ZSk7Cn0KdmFyIGlzQnVmZmVyID0gbmF0aXZlSXNCdWZmZXIgfHwgc3R1YkZhbHNlOwpmdW5jdGlvbiBpc0Z1bmN0aW9uKHZhbHVlKSB7CiAgaWYgKCFpc09iamVjdCh2YWx1ZSkpIHsKICAgIHJldHVybiBmYWxzZTsKICB9CiAgdmFyIHRhZyA9IGJhc2VHZXRUYWcodmFsdWUpOwogIHJldHVybiB0YWcgPT0gZnVuY1RhZyB8fCB0YWcgPT0gZ2VuVGFnIHx8IHRhZyA9PSBhc3luY1RhZyB8fCB0YWcgPT0gcHJveHlUYWc7Cn0KZnVuY3Rpb24gaXNMZW5ndGgodmFsdWUpIHsKICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdudW1iZXInICYmCiAgICB2YWx1ZSA+IC0xICYmIHZhbHVlICUgMSA9PSAwICYmIHZhbHVlIDw9IE1BWF9TQUZFX0lOVEVHRVI7Cn0KZnVuY3Rpb24gaXNPYmplY3QodmFsdWUpIHsKICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTsKICByZXR1cm4gdmFsdWUgIT0gbnVsbCAmJiAodHlwZSA9PSAnb2JqZWN0JyB8fCB0eXBlID09ICdmdW5jdGlvbicpOwp9CmZ1bmN0aW9uIGlzT2JqZWN0TGlrZSh2YWx1ZSkgewogIHJldHVybiB2YWx1ZSAhPSBudWxsICYmIHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0JzsKfQpmdW5jdGlvbiBpc1BsYWluT2JqZWN0KHZhbHVlKSB7CiAgaWYgKCFpc09iamVjdExpa2UodmFsdWUpIHx8IGJhc2VHZXRUYWcodmFsdWUpICE9IG9iamVjdFRhZykgewogICAgcmV0dXJuIGZhbHNlOwogIH0KICB2YXIgcHJvdG8gPSBnZXRQcm90b3R5cGUodmFsdWUpOwogIGlmIChwcm90byA9PT0gbnVsbCkgewogICAgcmV0dXJuIHRydWU7CiAgfQogIHZhciBDdG9yID0gaGFzT3duUHJvcGVydHkuY2FsbChwcm90bywgJ2NvbnN0cnVjdG9yJykgJiYgcHJvdG8uY29uc3RydWN0b3I7CiAgcmV0dXJuIHR5cGVvZiBDdG9yID09ICdmdW5jdGlvbicgJiYgQ3RvciBpbnN0YW5jZW9mIEN0b3IgJiYKICAgIGZ1bmNUb1N0cmluZy5jYWxsKEN0b3IpID09IG9iamVjdEN0b3JTdHJpbmc7Cn0KdmFyIGlzVHlwZWRBcnJheSA9IG5vZGVJc1R5cGVkQXJyYXkgPyBiYXNlVW5hcnkobm9kZUlzVHlwZWRBcnJheSkgOiBiYXNlSXNUeXBlZEFycmF5OwpmdW5jdGlvbiB0b1BsYWluT2JqZWN0KHZhbHVlKSB7CiAgcmV0dXJuIGNvcHlPYmplY3QodmFsdWUsIGtleXNJbih2YWx1ZSkpOwp9CmZ1bmN0aW9uIGtleXNJbihvYmplY3QpIHsKICByZXR1cm4gaXNBcnJheUxpa2Uob2JqZWN0KSA/IGFycmF5TGlrZUtleXMob2JqZWN0LCB0cnVlKSA6IGJhc2VLZXlzSW4ob2JqZWN0KTsKfQp2YXIgbWVyZ2UgPSBjcmVhdGVBc3NpZ25lcihmdW5jdGlvbihvYmplY3QsIHNvdXJjZSwgc3JjSW5kZXgpIHsKICBiYXNlTWVyZ2Uob2JqZWN0LCBzb3VyY2UsIHNyY0luZGV4KTsKfSk7CmZ1bmN0aW9uIGNvbnN0YW50KHZhbHVlKSB7CiAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIHZhbHVlOwogIH07Cn0KZnVuY3Rpb24gaWRlbnRpdHkodmFsdWUpIHsKICByZXR1cm4gdmFsdWU7Cn0KZnVuY3Rpb24gc3R1YkZhbHNlKCkgewogIHJldHVybiBmYWxzZTsKfQoKbW9kdWxlLmV4cG9ydHMgPSBtZXJnZTsKCn0pLmNhbGwodGhpcyx0eXBlb2YgZ2xvYmFsICE9PSAidW5kZWZpbmVkIiA/IGdsb2JhbCA6IHR5cGVvZiBzZWxmICE9PSAidW5kZWZpbmVkIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSAidW5kZWZpbmVkIiA/IHdpbmRvdyA6IHt9KTsKfSx7fV19LHt9LFsyXSkoMik7Cn0pOwp9KTsKCmFjZS5kZWZpbmUoImFjZS9tb2RlL3lhbWxfd29ya2VyIixbXSwgZnVuY3Rpb24ocmVxdWlyZSwgZXhwb3J0cykgewoidXNlIHN0cmljdCI7Cgp2YXIgb29wID0gcmVxdWlyZSgiLi4vbGliL29vcCIpOwp2YXIgTWlycm9yID0gcmVxdWlyZSgiLi4vd29ya2VyL21pcnJvciIpLk1pcnJvcjsKdmFyIGxpbnQgPSByZXF1aXJlKCIuL3lhbWwveWFtbC1saW50IikubGludDsKCnZhciBZYW1sV29ya2VyID0gZXhwb3J0cy5ZYW1sV29ya2VyID0gZnVuY3Rpb24oc2VuZGVyKSB7CiAgICBNaXJyb3IuY2FsbCh0aGlzLCBzZW5kZXIpOwogICAgdGhpcy5zZXRUaW1lb3V0KDUwMCk7CiAgICB0aGlzLnNldE9wdGlvbnMoKTsKfTsKCm9vcC5pbmhlcml0cyhZYW1sV29ya2VyLCBNaXJyb3IpOwoKKGZ1bmN0aW9uKCkgewogICAgdGhpcy5zZXRPcHRpb25zID0gZnVuY3Rpb24oKSB7CiAgICAgICAgdGhpcy5kb2MuZ2V0VmFsdWUoKSAmJiB0aGlzLmRlZmVycmVkVXBkYXRlLnNjaGVkdWxlKDEwMCk7CiAgICB9OwoKICAgIHRoaXMuY2hhbmdlT3B0aW9ucyA9IGZ1bmN0aW9uKG5ld09wdGlvbnMpIHsKICAgICAgICBvb3AubWl4aW4odGhpcy5vcHRpb25zLCBuZXdPcHRpb25zKTsKICAgICAgICB0aGlzLmRvYy5nZXRWYWx1ZSgpICYmIHRoaXMuZGVmZXJyZWRVcGRhdGUuc2NoZWR1bGUoMTAwKTsKICAgIH07CgogICAgdGhpcy5vblVwZGF0ZSA9IGZ1bmN0aW9uKCkgewogICAgICAgIHZhciBfdGhpcyA9IHRoaXM7CiAgICAgICAgdmFyIHZhbHVlID0gdGhpcy5kb2MuZ2V0VmFsdWUoKTsKICAgICAgICB2YXIgZXJyb3JzID0gW107CgogICAgICAgIGxpbnQodmFsdWUsIHt9LCBmdW5jdGlvbihlcnJvcikgewogICAgICAgICAgICBpZiAoIWVycm9yKSB7CiAgICAgICAgICAgICAgICBfdGhpcy5zZW5kZXIuZW1pdCgiYW5ub3RhdGUiLCBlcnJvcnMpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBtYXJrRGVmaW5lZCA9ICEhZXJyb3IubWFyazsKICAgICAgICAgICAgZXJyb3JzLnB1c2goewogICAgICAgICAgICAgICAgcm93OiBtYXJrRGVmaW5lZCA/IGVycm9yLm1hcmsubGluZSA6IDAsCiAgICAgICAgICAgICAgICBjb2x1bW46IG1hcmtEZWZpbmVkID8gZXJyb3IubWFyay5jb2x1bW4gOiAwLAogICAgICAgICAgICAgICAgdGV4dDogZXJyb3IucmVhc29uLAogICAgICAgICAgICAgICAgdHlwZTogJ2Vycm9yJywKICAgICAgICAgICAgICAgIHJhdzogZXJyb3IKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICBfdGhpcy5zZW5kZXIuZW1pdCgiYW5ub3RhdGUiLCBlcnJvcnMpOwogICAgICAgIH0pOwogICAgfTsKCn0pLmNhbGwoWWFtbFdvcmtlci5wcm90b3R5cGUpOwoKfSk7Cg=="), r.default.require("ace/ext/language_tools");
|
|
1429
|
-
//#endregion
|