@rainbow-robotics/muscat-plugin-kit 0.1.2-dev.9 → 0.10.1-dev.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/README.ko.md +1186 -0
- package/README.md +1137 -57
- package/cli/README.md +239 -7
- package/cli/bin/create-muscat-plugin.mjs +1 -1
- package/cli/bin/muscat-pk.mjs +123 -27
- package/cli/bundle-templates.mjs +31 -0
- package/cli/docker/Dockerfile.cpp +28 -0
- package/cli/docker/Dockerfile.dev +17 -0
- package/cli/docker/Dockerfile.python +21 -0
- package/cli/prepack.mjs +10 -0
- package/cli/src/__pycache__/host_agent.cpython-37.pyc +0 -0
- package/cli/src/ai-rules.mjs +107 -0
- package/cli/src/build.mjs +333 -93
- package/cli/src/check-package.mjs +8 -23
- package/cli/src/completion.mjs +168 -0
- package/cli/src/cpp.mjs +78 -0
- package/cli/src/cppIde.mjs +76 -0
- package/cli/src/dev.mjs +195 -6
- package/cli/src/devBack.mjs +671 -60
- package/cli/src/devId.mjs +54 -0
- package/cli/src/devSession.mjs +67 -0
- package/cli/src/devUi.mjs +214 -25
- package/cli/src/esbuild.mjs +27 -10
- package/cli/src/host_agent.py +223 -0
- package/cli/src/manifest.mjs +288 -0
- package/cli/src/mcp.mjs +1153 -0
- package/cli/src/mcpProxy.mjs +110 -0
- package/cli/src/muscatLocal.mjs +292 -0
- package/cli/src/new.mjs +205 -68
- package/cli/src/pluginDevServer.mjs +111 -0
- package/cli/src/ports.mjs +193 -0
- package/cli/src/projectCheck.mjs +102 -0
- package/cli/src/python.mjs +112 -0
- package/cli/src/ros2.mjs +62 -18
- package/cli/src/sdk.mjs +74 -24
- package/cli/src/sim.mjs +177 -0
- package/cli/src/storybook.mjs +150 -0
- package/cli/src/templates-embedded.mjs +4 -0
- package/cli/src/type.mjs +93 -34
- package/cli/src/uninstall.mjs +81 -0
- package/cli/src/update.mjs +364 -35
- package/cli/src/util.mjs +341 -11
- package/cli/src/zenohDev.mjs +83 -0
- package/cli/src/zip.mjs +121 -0
- package/cli/storybook-dist/_design-tokens.css +4957 -0
- package/cli/storybook-dist/_stories-src/NxAvatar.stories.tsx +27 -0
- package/cli/storybook-dist/_stories-src/NxPagination.stories.tsx +28 -0
- package/cli/storybook-dist/_stories-src/RBAccordion/RBAccordion.stories.tsx +46 -0
- package/cli/storybook-dist/_stories-src/RBAccordion/RBAccordionGroup.stories.tsx +73 -0
- package/cli/storybook-dist/_stories-src/RBBadge/RBBadge.stories.tsx +93 -0
- package/cli/storybook-dist/_stories-src/RBBattery/RBBattery.stories.tsx +74 -0
- package/cli/storybook-dist/_stories-src/RBButton/RBCheckIconButton.stories.tsx +28 -0
- package/cli/storybook-dist/_stories-src/RBButton/RBCheckLabelButton.stories.tsx +84 -0
- package/cli/storybook-dist/_stories-src/RBButton/RBIconButton.stories.tsx +57 -0
- package/cli/storybook-dist/_stories-src/RBButton/RBInlineLabelButton.stories.tsx +41 -0
- package/cli/storybook-dist/_stories-src/RBButton/RBLabelButton.stories.tsx +60 -0
- package/cli/storybook-dist/_stories-src/RBDatePicker/RBDateInput.stories.tsx +44 -0
- package/cli/storybook-dist/_stories-src/RBDatePicker/RBRangeDateInput.stories.tsx +56 -0
- package/cli/storybook-dist/_stories-src/RBDialog/RBAlert.stories.tsx +51 -0
- package/cli/storybook-dist/_stories-src/RBDialog/RBConfirm.stories.tsx +55 -0
- package/cli/storybook-dist/_stories-src/RBDialog/RBPrompt.stories.tsx +52 -0
- package/cli/storybook-dist/_stories-src/RBDivider/RBDivider.stories.tsx +93 -0
- package/cli/storybook-dist/_stories-src/RBEmptyView/RBEmptyView.stories.tsx +49 -0
- package/cli/storybook-dist/_stories-src/RBIcons/RBColorIcons.stories.tsx +108 -0
- package/cli/storybook-dist/_stories-src/RBIcons/RBIcons.stories.tsx +106 -0
- package/cli/storybook-dist/_stories-src/RBInput/RBCheckBox.stories.tsx +89 -0
- package/cli/storybook-dist/_stories-src/RBInput/RBMultiRangeInput.stories.tsx +64 -0
- package/cli/storybook-dist/_stories-src/RBInput/RBRadioBox.stories.tsx +65 -0
- package/cli/storybook-dist/_stories-src/RBInput/RBRadioButton.stories.tsx +68 -0
- package/cli/storybook-dist/_stories-src/RBInput/RBSelectBox.stories.tsx +216 -0
- package/cli/storybook-dist/_stories-src/RBInput/RBSideNumberInput.stories.tsx +90 -0
- package/cli/storybook-dist/_stories-src/RBInput/RBText/RBTextArea.stories.tsx +45 -0
- package/cli/storybook-dist/_stories-src/RBInput/RBText/RBTextInput.stories.tsx +50 -0
- package/cli/storybook-dist/_stories-src/RBInput/RBTextField.stories.tsx +102 -0
- package/cli/storybook-dist/_stories-src/RBJoyStick/RBJoyStick.stories.tsx +31 -0
- package/cli/storybook-dist/_stories-src/RBLight/RBLight.stories.tsx +36 -0
- package/cli/storybook-dist/_stories-src/RBPagination/RBPagination.stories.tsx +49 -0
- package/cli/storybook-dist/_stories-src/RBShadcn/RBCard/RBCard.stories.tsx +89 -0
- package/cli/storybook-dist/_stories-src/RBShadcn/RBCommand/RBCommand.stories.tsx +116 -0
- package/cli/storybook-dist/_stories-src/RBShadcn/RBDialog/RBDialog.stories.tsx +74 -0
- package/cli/storybook-dist/_stories-src/RBShadcn/RBDrawer/RBDrawer.stories.tsx +99 -0
- package/cli/storybook-dist/_stories-src/RBShadcn/RBDropdownMenu/RBDropdownMenu.stories.tsx +123 -0
- package/cli/storybook-dist/_stories-src/RBShadcn/RBMenubar/RBMenubar.stories.tsx +135 -0
- package/cli/storybook-dist/_stories-src/RBShadcn/RBPopover/RBPopover.stories.tsx +69 -0
- package/cli/storybook-dist/_stories-src/RBShadcn/RBResizable/RBResizable.stories.tsx +49 -0
- package/cli/storybook-dist/_stories-src/RBShadcn/RBSheet/RBSheet.stories.tsx +91 -0
- package/cli/storybook-dist/_stories-src/RBShadcn/RBSlider/RBSlider.stories.tsx +38 -0
- package/cli/storybook-dist/_stories-src/RBShadcn/RBSwitch/RBSwitch.stories.tsx +112 -0
- package/cli/storybook-dist/_stories-src/RBShadcn/RBTabs/RBTabs.stories.tsx +75 -0
- package/cli/storybook-dist/_stories-src/RBShadcn/RBToggle/RBToggle.stories.tsx +51 -0
- package/cli/storybook-dist/_stories-src/RBShadcn/RBToggleGroup/RBToggleGroup.stories.tsx +84 -0
- package/cli/storybook-dist/_stories-src/RBTab/RBChipTab.stories.tsx +102 -0
- package/cli/storybook-dist/_stories-src/RBTab/RBChipsBoxTab.stories.tsx +78 -0
- package/cli/storybook-dist/_stories-src/RBTab/RBTab.stories.tsx +57 -0
- package/cli/storybook-dist/_stories-src/RBTable/RBTable.stories.tsx +177 -0
- package/cli/storybook-dist/_stories-src/RBTable/RBTableRow.stories.tsx +64 -0
- package/cli/storybook-dist/_stories-src/RBToast/RBToast.stories.tsx +117 -0
- package/cli/storybook-dist/_stories-src/RBTooltip/RBTooltip.stories.tsx +50 -0
- package/cli/storybook-dist/_stories-src/loading/RBSpinner.stories.tsx +30 -0
- package/cli/storybook-dist/_stories-src/nx-button/NxButton.stories.tsx +54 -0
- package/cli/storybook-dist/_stories-src/nx-button/NxPointerHoldButton.stories.tsx +57 -0
- package/cli/storybook-dist/_stories-src/nx-icons/NxIcons.stories.tsx +48 -0
- package/cli/storybook-dist/_stories-src/nx-inputs/NxNumberInput.stories.tsx +103 -0
- package/cli/storybook-dist/_stories-src/nx-inputs/NxRangeInput.stories.tsx +27 -0
- package/cli/storybook-dist/_stories-src/nx-inputs/NxSelectBox.stories.tsx +67 -0
- package/cli/storybook-dist/_stories-src/nx-inputs/NxSlideRange.stories.tsx +45 -0
- package/cli/storybook-dist/_stories-src/nx-inputs/NxSwitch.stories.tsx +27 -0
- package/cli/storybook-dist/_stories-src/nx-inputs/NxTextArea.stories.tsx +48 -0
- package/cli/storybook-dist/_stories-src/nx-inputs/NxTextInput.stories.tsx +46 -0
- package/cli/storybook-dist/assets/Color-YHDXOIA2-pCKrjUal.js +1 -0
- package/cli/storybook-dist/assets/Docs-B-Y7I1GA.js +7 -0
- package/cli/storybook-dist/assets/Docs-BFJcE_VS.js +8 -0
- package/cli/storybook-dist/assets/Docs-B_QaTtz8.js +8 -0
- package/cli/storybook-dist/assets/Docs-CryDGmfh.js +20 -0
- package/cli/storybook-dist/assets/Docs-Cw2AVNKx.js +7 -0
- package/cli/storybook-dist/assets/Docs-Q6r1fBeL.js +12 -0
- package/cli/storybook-dist/assets/DocsRenderer-CFRXHY34-_OmZBCn8.js +2 -0
- package/cli/storybook-dist/assets/NxAvatar.stories-Ctf5G2FQ.js +13 -0
- package/cli/storybook-dist/assets/NxButton.stories-DeLObVSj.js +20 -0
- package/cli/storybook-dist/assets/NxIcons.stories-DeqrVzVs.js +3 -0
- package/cli/storybook-dist/assets/NxNumberInput.stories-LqoY0ed1.js +26 -0
- package/cli/storybook-dist/assets/NxPagination.stories-DI6bXuJM.js +11 -0
- package/cli/storybook-dist/assets/NxPointerHoldButton.stories-3HSV1XmN.js +14 -0
- package/cli/storybook-dist/assets/NxRangeInput.stories-1pjgQVaG.js +17 -0
- package/cli/storybook-dist/assets/NxSelectBox.stories-bcQPZEuF.js +17 -0
- package/cli/storybook-dist/assets/NxSlideRange.stories-BosX4axk.js +14 -0
- package/cli/storybook-dist/assets/NxSwitch.stories-DxV6dS33.js +11 -0
- package/cli/storybook-dist/assets/NxTextArea.stories-CO545-LP.js +11 -0
- package/cli/storybook-dist/assets/NxTextInput.stories-BP0npai1.js +11 -0
- package/cli/storybook-dist/assets/PretendardVariable-CJuje-Rk.woff2 +0 -0
- package/cli/storybook-dist/assets/RBAccordion.stories-fVR4Va2a.js +17 -0
- package/cli/storybook-dist/assets/RBAccordionGroup.stories-Du5bsckD.js +33 -0
- package/cli/storybook-dist/assets/RBAlert.stories-DNkMXUu6.js +17 -0
- package/cli/storybook-dist/assets/RBBadge.stories-C44pXt8D.js +1 -0
- package/cli/storybook-dist/assets/RBBattery.stories-DE2JHvfL.js +10 -0
- package/cli/storybook-dist/assets/RBCard.stories-CuIda7NI.js +45 -0
- package/cli/storybook-dist/assets/RBCheckBox.stories-D1qM1ayr.js +1 -0
- package/cli/storybook-dist/assets/RBCheckIconButton.stories-e4gkliBO.js +1 -0
- package/cli/storybook-dist/assets/RBCheckLabelButton.stories-CDzCtsMI.js +24 -0
- package/cli/storybook-dist/assets/RBChipTab.stories-DBrc_3Mp.js +21 -0
- package/cli/storybook-dist/assets/RBChipsBoxTab.stories-hlrsHjKY.js +1 -0
- package/cli/storybook-dist/assets/RBColorIcons.stories-BHUvpkdu.js +3 -0
- package/cli/storybook-dist/assets/RBCommand.stories-azAF41NP.js +73 -0
- package/cli/storybook-dist/assets/RBConfirm.stories-BMNjwbmT.js +20 -0
- package/cli/storybook-dist/assets/RBDateInput.stories-D0VezDzv.js +15 -0
- package/cli/storybook-dist/assets/RBDialog.stories-AOJ975Fy.js +38 -0
- package/cli/storybook-dist/assets/RBDivider.stories-NSvnj43Z.js +1 -0
- package/cli/storybook-dist/assets/RBDrawer.stories-Du0oTvD1.js +14 -0
- package/cli/storybook-dist/assets/RBDropdownMenu.stories-Hsxve4PW.js +86 -0
- package/cli/storybook-dist/assets/RBEmptyView.stories-BlwHx3zp.js +12 -0
- package/cli/storybook-dist/assets/RBIconButton.stories-DAPDY63x.js +1 -0
- package/cli/storybook-dist/assets/RBIcons.stories-W5ZUV2L1.js +3 -0
- package/cli/storybook-dist/assets/RBInlineLabelButton.stories-C99j0Y3g.js +1 -0
- package/cli/storybook-dist/assets/RBJoyStick.stories-Du0H1iAS.js +11 -0
- package/cli/storybook-dist/assets/RBLabelButton.stories-BlvHaU_Z.js +1 -0
- package/cli/storybook-dist/assets/RBLight.stories-BY6DKrre.js +1 -0
- package/cli/storybook-dist/assets/RBMenubar.stories-D2PEGpM9.js +3 -0
- package/cli/storybook-dist/assets/RBMultiRangeInput.stories-Bm2qSmjq.js +14 -0
- package/cli/storybook-dist/assets/RBPagination.stories-DDleJa5N.js +17 -0
- package/cli/storybook-dist/assets/RBPopover.stories-27YxPSFG.js +11 -0
- package/cli/storybook-dist/assets/RBPrompt.stories-BFaIOctr.js +20 -0
- package/cli/storybook-dist/assets/RBRadioBox.stories-BroDar0t.js +1 -0
- package/cli/storybook-dist/assets/RBRadioButton.stories-M3O-wX7V.js +11 -0
- package/cli/storybook-dist/assets/RBRangeDateInput.stories-CWlM_D5X.js +15 -0
- package/cli/storybook-dist/assets/RBResizable.stories-ui8X1qnc.js +20 -0
- package/cli/storybook-dist/assets/RBSelectBox.stories-C8T6cfA0.js +74 -0
- package/cli/storybook-dist/assets/RBSheet.stories-BCOo_Zcc.js +39 -0
- package/cli/storybook-dist/assets/RBSideNumberInput.stories-CU2_MVlJ.js +5 -0
- package/cli/storybook-dist/assets/RBSlider.stories-DgOp1TFc.js +5 -0
- package/cli/storybook-dist/assets/RBSpinner.stories-qLScY3zZ.js +14 -0
- package/cli/storybook-dist/assets/RBSwitch.stories-SXSY1QMb.js +65 -0
- package/cli/storybook-dist/assets/RBTab.stories-BzXXTsXP.js +1 -0
- package/cli/storybook-dist/assets/RBTable.stories-DHTeRNVk.js +62 -0
- package/cli/storybook-dist/assets/RBTableRow.stories-DRNRsd15.js +11 -0
- package/cli/storybook-dist/assets/RBTabs.stories-DP0noBLp.js +21 -0
- package/cli/storybook-dist/assets/RBTextArea.stories-TkaejfxJ.js +5 -0
- package/cli/storybook-dist/assets/RBTextField.stories-B6VpCGyt.js +45 -0
- package/cli/storybook-dist/assets/RBTextInput.stories-D3hZ08e-.js +5 -0
- package/cli/storybook-dist/assets/RBToast.stories-BQ2wS2U0.js +11 -0
- package/cli/storybook-dist/assets/RBToggle.stories-GVOjGqo3.js +12 -0
- package/cli/storybook-dist/assets/RBToggleGroup.stories-pzx0btOD.js +17 -0
- package/cli/storybook-dist/assets/RBTooltip.stories-jufB6fa1.js +9 -0
- package/cli/storybook-dist/assets/SideNumberInput-BYlmNHEw.js +1109 -0
- package/cli/storybook-dist/assets/SideNumberInput-SAkhydsn.css +21 -0
- package/cli/storybook-dist/assets/browserUtils-CQM9Za7e.js +1 -0
- package/cli/storybook-dist/assets/chunk-XP5HYGXS-BHXC9YeQ.js +1 -0
- package/cli/storybook-dist/assets/client-DTf7SId2.js +1 -0
- package/cli/storybook-dist/assets/entry-preview-CAkU-e0D.js +2 -0
- package/cli/storybook-dist/assets/entry-preview-docs-b8bpVBXy.js +46 -0
- package/cli/storybook-dist/assets/iframe-B-BmTsxV.js +211 -0
- package/cli/storybook-dist/assets/index-B4FGfHer.js +1 -0
- package/cli/storybook-dist/assets/index-BRq5TIsn.js +24 -0
- package/cli/storybook-dist/assets/index-CT3U1fyk.js +1 -0
- package/cli/storybook-dist/assets/index-ChsGqxH_.js +9 -0
- package/cli/storybook-dist/assets/index-CkB0GfaI.js +575 -0
- package/cli/storybook-dist/assets/index-ClAc6FBW.js +240 -0
- package/cli/storybook-dist/assets/index-DKFBREX_.js +1 -0
- package/cli/storybook-dist/assets/index-DgH-xKnr.js +11 -0
- package/cli/storybook-dist/assets/index-Dmy2JGbm.js +1 -0
- package/cli/storybook-dist/assets/index-DrFu-skq.js +6 -0
- package/cli/storybook-dist/assets/jsx-runtime-BTJTZTIL.js +9 -0
- package/cli/storybook-dist/assets/preview-B8lJiyuQ.js +34 -0
- package/cli/storybook-dist/assets/preview-BBWR9nbA.js +1 -0
- package/cli/storybook-dist/assets/preview-BVJwlGUF.js +1 -0
- package/cli/storybook-dist/assets/preview-BWzBA1C2.js +396 -0
- package/cli/storybook-dist/assets/preview-CVgpLj3b.js +1 -0
- package/cli/storybook-dist/assets/preview-CvbIS5ZJ.js +1 -0
- package/cli/storybook-dist/assets/preview-CznQwwbo.js +3 -0
- package/cli/storybook-dist/assets/preview-DD_OYowb.js +1 -0
- package/cli/storybook-dist/assets/preview-DGUiP6tS.js +7 -0
- package/cli/storybook-dist/assets/preview-DHQbi4pV.js +1 -0
- package/cli/storybook-dist/assets/preview-M77JRg1A.js +2 -0
- package/cli/storybook-dist/assets/preview-kTZPgP6D.css +1 -0
- package/cli/storybook-dist/assets/react-18-hB3smqWJ.js +1 -0
- package/cli/storybook-dist/assets/react-resizable-panels-HsFbxPbn.css +1 -0
- package/cli/storybook-dist/assets/react-resizable-panels.browser-DuxpZLkF.js +120 -0
- package/cli/storybook-dist/assets/test-utils-BQudk2xt.js +9 -0
- package/cli/storybook-dist/favicon.svg +1 -0
- package/cli/storybook-dist/iframe.html +666 -0
- package/cli/storybook-dist/index.html +190 -0
- package/cli/storybook-dist/index.json +1 -0
- package/cli/storybook-dist/nunito-sans-bold-italic.woff2 +0 -0
- package/cli/storybook-dist/nunito-sans-bold.woff2 +0 -0
- package/cli/storybook-dist/nunito-sans-italic.woff2 +0 -0
- package/cli/storybook-dist/nunito-sans-regular.woff2 +0 -0
- package/cli/storybook-dist/project.json +1 -0
- package/cli/storybook-dist/sb-addons/chromatic-com-storybook-10/manager-bundle.js +331 -0
- package/cli/storybook-dist/sb-addons/chromatic-com-storybook-10/manager-bundle.js.LEGAL.txt +51 -0
- package/cli/storybook-dist/sb-addons/essentials-actions-3/manager-bundle.js +3 -0
- package/cli/storybook-dist/sb-addons/essentials-backgrounds-5/manager-bundle.js +12 -0
- package/cli/storybook-dist/sb-addons/essentials-controls-2/manager-bundle.js +405 -0
- package/cli/storybook-dist/sb-addons/essentials-docs-4/manager-bundle.js +245 -0
- package/cli/storybook-dist/sb-addons/essentials-measure-8/manager-bundle.js +3 -0
- package/cli/storybook-dist/sb-addons/essentials-outline-9/manager-bundle.js +3 -0
- package/cli/storybook-dist/sb-addons/essentials-toolbars-7/manager-bundle.js +3 -0
- package/cli/storybook-dist/sb-addons/essentials-viewport-6/manager-bundle.js +3 -0
- package/cli/storybook-dist/sb-addons/links-1/manager-bundle.js +3 -0
- package/cli/storybook-dist/sb-addons/storybook-13/manager-bundle.js +3 -0
- package/cli/storybook-dist/sb-addons/storybook-core-core-server-presets-0/common-manager-bundle.js +3 -0
- package/cli/storybook-dist/sb-addons/storybook-experimental-addon-test-12/manager-bundle.js +223 -0
- package/cli/storybook-dist/sb-addons/themes-11/manager-bundle.js +3 -0
- package/cli/storybook-dist/sb-common-assets/favicon.svg +1 -0
- package/cli/storybook-dist/sb-common-assets/nunito-sans-bold-italic.woff2 +0 -0
- package/cli/storybook-dist/sb-common-assets/nunito-sans-bold.woff2 +0 -0
- package/cli/storybook-dist/sb-common-assets/nunito-sans-italic.woff2 +0 -0
- package/cli/storybook-dist/sb-common-assets/nunito-sans-regular.woff2 +0 -0
- package/cli/storybook-dist/sb-manager/globals-module-info.js +1052 -0
- package/cli/storybook-dist/sb-manager/globals-runtime.js +41775 -0
- package/cli/storybook-dist/sb-manager/globals.js +48 -0
- package/cli/storybook-dist/sb-manager/runtime.js +12048 -0
- package/cli/templates/common/README.md +1070 -83
- package/cli/templates/common/assets/icon.svg +44 -2
- package/cli/templates/common/manifest.json +14 -13
- package/cli/templates/common/package.json +11 -4
- package/cli/templates/common/py/main.py +125 -0
- package/cli/templates/common/requirements.txt +4 -3
- package/cli/templates/common/tsconfig.json +1 -1
- package/cli/templates/common/ui/content.tsx +216 -0
- package/cli/templates/common/ui/style.css +6 -0
- package/cli/templates/common/vite.config.ts +6 -25
- package/cli/templates/cpp/cpp/CMakeLists.txt +14 -0
- package/cli/templates/cpp/cpp/main.cpp +73 -0
- package/cli/templates/readme-cpp/README.md +1012 -0
- package/cli/templates/ros2/ros2_ws/src/__PLUGIN_SLUG__/__PLUGIN_SLUG__/node.py +12 -1
- package/cli/templates/ros2-cpp/ros2_ws/src/__PLUGIN_SLUG__/CMakeLists.txt +22 -0
- package/cli/templates/ros2-cpp/ros2_ws/src/__PLUGIN_SLUG__/package.xml +11 -0
- package/cli/templates/ros2-cpp/ros2_ws/src/__PLUGIN_SLUG__/src/node.cpp +41 -0
- package/cli/vite.d.mts +25 -0
- package/cli/vite.mjs +292 -0
- package/package.json +34 -7
- package/cli/src/pack.mjs +0 -61
- package/cli/src/preview.mjs +0 -91
- package/cli/templates/common/main.py +0 -114
- package/cli/templates/common/src/content.tsx +0 -33
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// AUTO-GENERATED by cli/bundle-templates.mjs — do not edit.
|
|
2
|
+
// ponytail: generated at publish time; not tracked in git.
|
|
3
|
+
export const KIT_VERSION = "1.10.2-dev.6";
|
|
4
|
+
export const TEMPLATES = {"common/README.md":"IyBfX1BMVUdJTl9OQU1FX18KCkEgTXVzY2F0IHBsdWdpbiBwcm9qZWN0LiBCdWlsZCwgZGV2ZWxvcCwgYW5kIHNoaXAgd2l0aCBgbXVzY2F0LXBrYCBDTEkuCgojIyBRdWljayBzdGFydAoKYGBgYmFzaAptdXNjYXQtcGsgZGV2ICAgICAgICAjIFVJIHByZXZpZXcgKyBiYWNrZW5kIHRvZ2V0aGVyCm11c2NhdC1wayBkZXY6dWkgICAgICMgVUkgcHJldmlldyBvbmx5Cm11c2NhdC1wayBkZXY6YmFjayAgICMgYmFja2VuZCBvbmx5IChQeXRob24gd2F0Y2hmaWxlcyAvIFJPUzIgRG9ja2VyKQptdXNjYXQtcGsgYnVpbGQgICAgICAjIGJ1aWxkICsgZGlzdHJpYnV0YWJsZSBaSVAKYGBgCgotLS0KCiMjIFByb2plY3Qgc3RydWN0dXJlCgpgYGAKX19QTFVHSU5fRElSX18vCuKUnOKUgCB1aS8K4pSCICAg4pSc4pSAIGNvbnRlbnQudHN4ICAgICAgIyBwbHVnaW4gVUkgZW50cnkgcG9pbnQK4pSCICAg4pSU4pSAIHN0eWxlLmNzcyAgICAgICAgIyBwbHVnaW4gc3R5bGVzIGF1dG8tbG9hZGVkIGJ5IG11c2NhdCgpCuKUnOKUgCBweS8K4pSCICAg4pSU4pSAIG1haW4ucHkgICAgICAgICAgIyBQeXRob24gYmFja2VuZCBlbnRyeSBwb2ludArilJzilIAgYXNzZXRzLwrilIIgICDilJTilIAgaWNvbi5zdmcgICAgICAgICAjIGljb24gcmVmZXJlbmNlZCBmcm9tIG1hbmlmZXN0CuKUnOKUgCBtYW5pZmVzdC5qc29uICAgICAgICAjIG1ldGFkYXRhLCBjb250cmlidXRpb24gcG9pbnRzLCBydW50aW1lIGNvbmZpZwrilJzilIAgUkVBRE1FLm1kICAgICAgICAgICAgIyB0aGlzIGZpbGUgKGNvcGllZCB0byBkaXN0LyBvbiBidWlsZCkK4pSU4pSAIHJlcXVpcmVtZW50cy50eHQgICAgICMgUHl0aG9uIGRlcHMgKGF1dG8tcGlubmVkIHRvIGxhdGVzdCBvbiBidWlsZCkKYGBgCgo+IFJPUzIgcGx1Z2lucyBhZGRpdGlvbmFsbHkgaW5jbHVkZSBhIGByb3MyX3dzL2AgZGlyZWN0b3J5LgoKLS0tCgojIyBGcm9udGVuZCAoYHVpL2NvbnRlbnQudHN4YCkKCiMjIyBKYXZhU2NyaXB0IGRlcGVuZGVuY2llcwoKYG11c2NhdC1wayBidWlsZGAgcnVucyB0aGlzIHBsdWdpbiBwcm9qZWN0J3Mgb3duIFZpdGUgYnVpbGQuIFZpdGUgcmVzb2x2ZXMKaW1wb3J0cyBmcm9tIGluc3RhbGxlZCBgbm9kZV9tb2R1bGVzYDsgaXQgZG9lcyBub3QgY2FyZSB3aGV0aGVyIGEgcGFja2FnZSBpcwpsaXN0ZWQgdW5kZXIgYGRlcGVuZGVuY2llc2Agb3IgYGRldkRlcGVuZGVuY2llc2AsIGJ1dCB0aGUgcGFja2FnZSBtdXN0IGJlCmluc3RhbGxlZC4KCkRvIG5vdCBydW4gYSBwcm9kdWN0aW9uLW9ubHkgaW5zdGFsbCBzdWNoIGFzIGBucG0gaW5zdGFsbCAtLW9taXQ9ZGV2YCBiZWZvcmUKYnVpbGRpbmcgdGhlIHBsdWdpbiBVSSwgYmVjYXVzZSBidWlsZCB0b29scyBsaWtlIGB2aXRlYCwgYHR5cGVzY3JpcHRgLApgdGFpbHdpbmRjc3NgLCBgQHRhaWx3aW5kY3NzL3ZpdGVgLCBgc2Fzc2AsIG9yIGBsZXNzYCBhcmUgdXN1YWxseQpgZGV2RGVwZW5kZW5jaWVzYC4KClRoZSBzY2FmZm9sZCBrZWVwcyB0aGlzIHNwbGl0OgoKfCBwYWNrYWdlIGtpbmQgfCBleGFtcGxlcyB8IHdoeSB8CnwtLS18LS0tfC0tLXwKfCBgZGVwZW5kZW5jaWVzYCB8IGBAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWlgLCBVSSBsaWJyYXJpZXMgaW1wb3J0ZWQgYnkgcGx1Z2luIHNvdXJjZSB8IEF1dGhvci1mYWNpbmcgQVBJcyB1c2VkIGJ5IGB1aS8qLnRzeGAgfAp8IGBkZXZEZXBlbmRlbmNpZXNgIHwgYHZpdGVgLCBgdHlwZXNjcmlwdGAsIGB0YWlsd2luZGNzc2AsIGBAdGFpbHdpbmRjc3Mvdml0ZWAsIGBzYXNzYCwgYGxlc3NgIHwgQnVpbGQvZGV2IHRvb2xzIG5lZWRlZCBiZWZvcmUgYGRpc3QvKi5qc2AgaXMgcHJvZHVjZWQgfAoKVGhlIGJ1aWx0IHBsdWdpbiBaSVAgZG9lcyBub3QgaW5jbHVkZSBgcGFja2FnZS5qc29uYCBvciBgbm9kZV9tb2R1bGVzYC4gRm9yCnByb2R1Y3Rpb24sIE11c2NhdCBwcm92aWRlcyBgQHJhaW5ib3ctcm9ib3RpY3MvcGx1Z2luLXVpYCwgUmVhY3QsIGFuZCBSZWFjdERPTQp0aHJvdWdoIHRoZSBob3N0IGltcG9ydCBtYXA7IHBsdWdpbiBVSSBidWlsZCBvdXRwdXQgaW1wb3J0cyB0aG9zZSBhcyBob3N0CmV4dGVybmFscy4KCiMjIyBTdHlsZXMKCmBtdXNjYXQoKWAgYXV0b21hdGljYWxseSBsb2FkcyBgdWkvc3R5bGUue2NzcyxzY3NzLHNhc3MsbGVzc31gIChvcgpgdWkvc3R5bGVzLntjc3Msc2NzcyxzYXNzLGxlc3N9YCkgZm9yIGV2ZXJ5IFVJIGVudHJ5LCBwbHVzCmB1aS97ZW50cnl9Lntjc3Msc2NzcyxzYXNzLGxlc3N9YCBmb3IgYSBtYXRjaGluZyBlbnRyeS1zcGVjaWZpYyBzdHlsZXNoZWV0LiBZb3UKZG8gbm90IG5lZWQgdG8gaW1wb3J0IENTUyBmcm9tIGV2ZXJ5IGAudHN4YCBmaWxlLgoKVGhlIHNjYWZmb2xkIHVzZXMgVGFpbHdpbmQncyB0aGVtZS91dGlsaXRpZXMgbGF5ZXJzIG9ubHksIHNvIHBsdWdpbiB1dGlsaXRpZXMKYXJlIGdlbmVyYXRlZCBmcm9tIGZpbGVzIHVuZGVyIGB1aS9gIHdpdGhvdXQgYXBwbHlpbmcgVGFpbHdpbmQgcHJlZmxpZ2h0IHJlc2V0cwp0byB0aGUgaG9zdCBwYWdlLgoKQnVpbHQgQ1NTIHNlbGVjdG9ycyBhcmUgc2NvcGVkIHVuZGVyIHRoZSBjdXJyZW50IHBsdWdpbiBpZAooYFtkYXRhLW11c2NhdC1wbHVnaW4taWQ9Ii4uLiJdYCkuIENTUy1pbi1KUyBsaWJyYXJpZXMgc3VjaCBhcyBFbW90aW9uIHdvcmsKbm9ybWFsbHksIGJ1dCBnbG9iYWwgc3R5bGVzIHNob3VsZCBiZSBzY29wZWQgYnkgdGhlIGF1dGhvci4KCiMjIyMgVGFpbHdpbmQKClRoaXMgdGVtcGxhdGUgZW5hYmxlcyBUYWlsd2luZCBpbiBgdml0ZS5jb25maWcudHNgOgoKYGBgdHMKaW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAidml0ZSI7CmltcG9ydCB0YWlsd2luZGNzcyBmcm9tICJAdGFpbHdpbmRjc3Mvdml0ZSI7CmltcG9ydCB7IG11c2NhdCB9IGZyb20gIkByYWluYm93LXJvYm90aWNzL211c2NhdC1wbHVnaW4ta2l0L3ZpdGUiOwoKZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHsKICBwbHVnaW5zOiBbdGFpbHdpbmRjc3MoKSwgbXVzY2F0KCldLAp9KTsKYGBgCgpUaGUgZGVmYXVsdCBgdWkvc3R5bGUuY3NzYCB1c2VzIFRhaWx3aW5kIHRoZW1lL3V0aWxpdGllcyBvbmx5LCBub3QgcHJlZmxpZ2h0OgoKYGBgY3NzCkBsYXllciB0aGVtZSwgdXRpbGl0aWVzOwoKQGltcG9ydCAidGFpbHdpbmRjc3MvdGhlbWUuY3NzIiBsYXllcih0aGVtZSk7CkBpbXBvcnQgInRhaWx3aW5kY3NzL3V0aWxpdGllcy5jc3MiIGxheWVyKHV0aWxpdGllcyk7CgpAc291cmNlICIuLyoqLyoue3RzLHRzeH0iOwpgYGAKCiMjIyMgU0NTUywgU2FzcywgYW5kIExlc3MKCkluc3RhbGwgdGhlIHByZXByb2Nlc3NvciBwYWNrYWdlLCB0aGVuIGNyZWF0ZSBvbmUgb2YgdGhlIGF1dG8tbG9hZGVkIHN0eWxlIGZpbGVzLgoKYGBgYmFzaApucG0gaSAtRCBzYXNzCmBgYAoKYGBgc2NzcwovKiB1aS9zdHlsZS5zY3NzICovCiRhY2NlbnQ6ICMzYjgyZjY7CgoucGFuZWwgewogIGJvcmRlcjogMXB4IHNvbGlkIGNvbG9yLW1peChpbiBzcmdiLCAkYWNjZW50IDQwJSwgdHJhbnNwYXJlbnQpOwoKICAmX190aXRsZSB7CiAgICBjb2xvcjogJGFjY2VudDsKICB9Cn0KYGBgCgpGb3IgTGVzcywgaW5zdGFsbCBgbGVzc2AgYW5kIHVzZSBgdWkvc3R5bGUubGVzc2AuCgojIyMjIEVtb3Rpb24KCkVtb3Rpb24gZGVwZW5kZW5jaWVzIG1heSBiZSBpbiBgZGVwZW5kZW5jaWVzYCBvciBgZGV2RGVwZW5kZW5jaWVzYDsgVml0ZSBjYW4KYnVuZGxlIHRoZW0gd2hlbiB0aGV5IGFyZSBpbnN0YWxsZWQgYW5kIGltcG9ydGVkIGJ5IHRoZSBwbHVnaW4uCgpGb3IgYHN0eWxlZGAsIG5vIFZpdGUgY29uZmlnIGNoYW5nZSBpcyBuZWVkZWQ6CgpgYGBiYXNoCm5wbSBpIEBlbW90aW9uL3JlYWN0IEBlbW90aW9uL3N0eWxlZApgYGAKCmBgYHRzeAppbXBvcnQgc3R5bGVkIGZyb20gIkBlbW90aW9uL3N0eWxlZCI7Cgpjb25zdCBQYW5lbCA9IHN0eWxlZC5kaXYoewogIGRpc3BsYXk6ICJncmlkIiwKICBnYXA6IDEyLAp9KTsKYGBgCgpGb3IgRW1vdGlvbidzIGBjc3NgIHByb3AsIHBhc3MgUmVhY3QgcGx1Z2luIG9wdGlvbnMgdGhyb3VnaCBgbXVzY2F0KClgIGFuZCBhZGQKYGpzeEltcG9ydFNvdXJjZWAgdG8gYHRzY29uZmlnLmpzb25gOgoKYGBgYmFzaApucG0gaSBAZW1vdGlvbi9yZWFjdCBAZW1vdGlvbi9zdHlsZWQKbnBtIGkgLUQgQGVtb3Rpb24vYmFiZWwtcGx1Z2luCmBgYAoKYGBgdHMKLy8gdml0ZS5jb25maWcudHMKaW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAidml0ZSI7CmltcG9ydCB0YWlsd2luZGNzcyBmcm9tICJAdGFpbHdpbmRjc3Mvdml0ZSI7CmltcG9ydCB7IG11c2NhdCB9IGZyb20gIkByYWluYm93LXJvYm90aWNzL211c2NhdC1wbHVnaW4ta2l0L3ZpdGUiOwoKZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHsKICBwbHVnaW5zOiBbCiAgICB0YWlsd2luZGNzcygpLAogICAgbXVzY2F0KHsKICAgICAgcmVhY3Q6IHsKICAgICAgICBqc3hJbXBvcnRTb3VyY2U6ICJAZW1vdGlvbi9yZWFjdCIsCiAgICAgICAgYmFiZWw6IHsKICAgICAgICAgIHBsdWdpbnM6IFsiQGVtb3Rpb24vYmFiZWwtcGx1Z2luIl0sCiAgICAgICAgfSwKICAgICAgfSwKICAgIH0pLAogIF0sCn0pOwpgYGAKCmBgYGpzb24KewogICJjb21waWxlck9wdGlvbnMiOiB7CiAgICAianN4SW1wb3J0U291cmNlIjogIkBlbW90aW9uL3JlYWN0IgogIH0KfQpgYGAKCkVtb3Rpb24gYEdsb2JhbGAgd3JpdGVzIGdsb2JhbCBDU1MgYXQgcnVudGltZSwgc28gc2NvcGUgaXQgbWFudWFsbHkgb3IgYXZvaWQgaXQKaW5zaWRlIHBsdWdpbnMuCgojIyMgdXNlUmIoKSBob29rCgpBY2Nlc3MgdGhlIGNvbW11bmljYXRpb24gQVBJIGJldHdlZW4gdGhlIHBsdWdpbiBtb2R1bGUgYW5kIFVJIGZyb20gYW55IHBsdWdpbiBjb21wb25lbnQuCgpgYGB0c3gKaW1wb3J0IHsgdXNlUmIgfSBmcm9tICJAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWkvc2RrIjsKCmZ1bmN0aW9uIEFwcCgpIHsKICBjb25zdCByYiA9IHVzZVJiKCk7Cn0KYGBgCgojIyMgcmIgQVBJCgp8IE1ldGhvZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IERlc2NyaXB0aW9uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAp8IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB8IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gfAp8IGByYi5wdWIodG9waWMsIHBheWxvYWQpYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFB1Ymxpc2ggYSBtZXNzYWdlIHRvIGEgdG9waWMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAp8IGByYi5zdWIodG9waWMsIGhhbmRsZXIpYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFN1YnNjcmliZSB0byBhIHRvcGljIOKAlCByZXR1cm5zIGB7IHVuZGVjbGFyZSgpIH1gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLmFjdGlvbih0b3BpYywgcGF5bG9hZD8pYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU2VuZCBhIHJlcXVlc3QgYW5kIGF3YWl0IGEgcmVwbHkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLnNlcnZlKHRvcGljLCBoYW5kbGVyKWAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgSGFuZGxlIGluY29taW5nIHJlcXVlc3RzIGZyb20gdGhlIGJhY2tlbmQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLnRvYXN0KHsgdGl0bGU/LCBtZXNzYWdlLCB0eXBlPywgYWN0aW9uTGFiZWw/LCBoYW5kbGVBY3Rpb25DbGljaz8sIGNsb3NlT25BY3Rpb25DbGljaz8sIGR1cmF0aW9uPywgb25DbG9zZT8gfSlgIHwgU2hvdyBhIGhvc3QgdG9hc3Qgbm90aWZpY2F0aW9uLiBgbWVzc2FnZWAgYWNjZXB0cyBhIHN0cmluZyBvciBgUmVhY3RFbGVtZW50YC4gYHR5cGVgIGNhbiBiZSBgImluZm8iYCwgYCJkYW5nZXIiYCwgYCJ3YXJuaW5nImAsIGAiY2F1dGlvbiJgLCBvciBgInN1Y2Nlc3MiYCB8CnwgYHJiLmFsZXJ0KHsgdGl0bGU/LCBtZXNzYWdlLCBidXR0b25UZXh0PyB9KWAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU2hvdyBhIGhvc3QgYWxlcnQgZGlhbG9nLiBSZXNvbHZlcyB3aGVuIHRoZSBkaWFsb2cgaXMgY2xvc2VkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLmNvbmZpcm0oeyB0aXRsZT8sIG1lc3NhZ2UsIGJ1dHRvblRleHQ/IH0pYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU2hvdyBhIGhvc3QgY29uZmlybWF0aW9uIGRpYWxvZy4gYGJ1dHRvblRleHRgIGFjY2VwdHMgYHsgeWVzLCBubyB9YC4gUmVzb2x2ZXMgdG8gYHRydWVgIG9yIGBmYWxzZWAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLnByb21wdCh7IHRpdGxlPywgbWVzc2FnZSwgdmFsdWU/LCBwbGFjZWhvbGRlcj8sIGJ1dHRvblRleHQ/IH0pYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU2hvdyBhIGhvc3QgcHJvbXB0IGRpYWxvZy4gYGJ1dHRvblRleHRgIGFjY2VwdHMgYHsgeWVzLCBubyB9YC4gUmVzb2x2ZXMgdG8gdGhlIGVudGVyZWQgc3RyaW5nIG9yIGB1bmRlZmluZWRgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CgpUb3BpYyBuYW1lcyBwYXNzZWQgdG8gYHB1YmAsIGBzdWJgLCBgYWN0aW9uYCwgYW5kIGBzZXJ2ZWAgYXJlIGlzb2xhdGVkIHBlciBwbHVnaW4uCgoKQWxsIG1ldGhvZHMgc3VwcG9ydCBHZW5lcmljIFR5cGVzOgoKYGBgdHN4CmNvbnN0IHN0YXR1cyA9IGF3YWl0IHJiLmFjdGlvbjx7IG9rOiBib29sZWFuIH0sIHsgaWQ6IG51bWJlciB9PigKICAiZ2V0LXN0YXR1cyIsCiAgeyBpZDogMSB9LAopOwoKY29uc3Qgc3ViID0gYXdhaXQgcmIuc3ViPHsgdmFsdWU6IG51bWJlciB9Pigic2Vuc29yL2RhdGEiLCAoZGF0YSkgPT4gewogIGNvbnNvbGUubG9nKGRhdGEudmFsdWUpOwp9KTsKc3ViLnVuZGVjbGFyZSgpOyAvLyBjbGVhbnVwCgpjb25zdCBvayA9IGF3YWl0IHJiLmNvbmZpcm0oewogIHRpdGxlOiAiUnVuIiwKICBtZXNzYWdlOiAiU3RhcnQgdGhlIGJhY2tlbmQgYWN0aW9uPyIsCn0pOwppZiAob2spIHsKICBhd2FpdCByYi5hY3Rpb24oInJ1biIpOwp9CmBgYAoKIyMjIFNhdmluZyBhbmQgcmVzdG9yaW5nIGZvcm0gZGF0YSAoYHVzZVJiRm9ybURhdGFgIC8gYHVzZVJiU2F2ZWApCgpJZiB0aGUgaG9zdCBlbWJlZHMgeW91ciBwbHVnaW4gaW4gYSBmb3JtIGl0IG93bnMgKGUuZy4gYSBwcm9ncmFtIHN0ZXAgZWRpdG9yCndpdGggaXRzIG93biBTYXZlIGJ1dHRvbiksIGl0IGNhbiBoYW5kIHlvdXIgcGx1Z2luIHByZXZpb3VzbHktc2F2ZWQgdmFsdWVzIGFuZApwdWxsIHRoZSBjdXJyZW50IHZhbHVlcyBiYWNrIG91dCB3aGVuIHRoZSB1c2VyIHNhdmVzLiBUaGUgaG9zdCDigJQgbm90IHRoZQpwbHVnaW4g4oCUIHBlcnNpc3RzIHRoZSBkYXRhIChJbmRleGVkREIsIGJhY2tlbmQsIGV0Yy4pLgoKYGBgdHN4CmltcG9ydCB7IHVzZVN0YXRlIH0gZnJvbSAicmVhY3QiOwppbXBvcnQgeyB1c2VSYkZvcm1EYXRhLCB1c2VSYlNhdmUgfSBmcm9tICJAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWkvcmVhY3QiOwoKdHlwZSBHcmlwQXJncyA9IHsgdGFyZ2V0TmFtZTogc3RyaW5nOyB3aWR0aDogbnVtYmVyIH07CmNvbnN0IERFRkFVTFRTOiBHcmlwQXJncyA9IHsgdGFyZ2V0TmFtZTogIiIsIHdpZHRoOiAyMCB9OwoKZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQXBwKCkgewogIC8vIFByZXZpb3VzbHktc2F2ZWQgdmFsdWVzLCBvciB1bmRlZmluZWQgZm9yIGEgYnJhbmQtbmV3IGluc3RhbmNlLgogIGNvbnN0IHNhdmVkID0gdXNlUmJGb3JtRGF0YTxHcmlwQXJncz4oKTsKICBjb25zdCBbYXJncywgc2V0QXJnc10gPSB1c2VTdGF0ZTxHcmlwQXJncz4oeyAuLi5ERUZBVUxUUywgLi4uc2F2ZWQgfSk7CgogIC8vIFJlZ2lzdGVycyBhIGdldHRlciB0aGUgaG9zdCBjYWxscyB3aGVuIGl0cyBTYXZlIGJ1dHRvbiBpcyBjbGlja2VkLgogIC8vIEFsd2F5cyByZXR1cm5zIHRoZSBDVVJSRU5UIHZhbHVlcyDigJQgcmUtcmVnaXN0ZXJpbmcgb24gZXZlcnkgcmVuZGVyIGtlZXBzCiAgLy8gdGhlIGNsb3N1cmUgZnJlc2gsIHdoaWNoIHVzZVJiU2F2ZSBhbHJlYWR5IGhhbmRsZXMgZm9yIHlvdS4KICB1c2VSYlNhdmUoKCkgPT4gKHsKICAgIGFyZ3MsCiAgICBzdW1tYXJ5OiBgJHthcmdzLnRhcmdldE5hbWUgfHwgInRhcmdldCJ9IMK3ICR7YXJncy53aWR0aH1tbWAsCiAgfSkpOwoKICByZXR1cm4gKC8qIC4uLmZvcm0gVUkgcmVhZGluZy93cml0aW5nIGBhcmdzYC4uLiAqLyk7Cn0KYGBgCgpUaGUgdmFsdWUgcmV0dXJuZWQgZnJvbSBgdXNlUmJTYXZlYCBtdXN0IGJlIEpTT04tc2VyaWFsaXNhYmxlIOKAlCB0aGUgaG9zdApwZXJzaXN0cyBpdCBhcy1pcy4gTm90IGV2ZXJ5IGhvc3QgZW1iZWRzIHBsdWdpbnMgaW4gYSBzYXZlL3Jlc3RvcmUgZm9ybTsgaWYKeW91cnMgZG9lc24ndCwgeW91IGNhbiBza2lwIHRoZXNlIGhvb2tzIGVudGlyZWx5LgoKIyMjIFVJIGNvbXBvbmVudHMKCkltcG9ydCBNdXNjYXQgY29tcG9uZW50cyBmcm9tIGBAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWkvcmVhY3RgIGFuZCBleHBvcnQgYQpSZWFjdCBjb21wb25lbnQgYXMgdGhlIGRlZmF1bHQgZXhwb3J0LiBUaGUgaG9zdCBtb3VudHMgdGhhdCBjb21wb25lbnQgZGlyZWN0bHkKYW5kIHByb3ZpZGVzIGB1c2VSYigpYCB0aHJvdWdoIGNvbnRleHQuCgpgYGB0c3gKaW1wb3J0IHsgdXNlU3RhdGUgfSBmcm9tICJyZWFjdCI7CmltcG9ydCB7IFJCTGFiZWxCdXR0b24sIFJCU2xpZGVyLCBSQlN3aXRjaCB9IGZyb20gIkByYWluYm93LXJvYm90aWNzL3BsdWdpbi11aS9yZWFjdCI7CmltcG9ydCB7IHVzZVJiIH0gZnJvbSAiQHJhaW5ib3ctcm9ib3RpY3MvcGx1Z2luLXVpL3NkayI7CgpleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBBcHAoKSB7CiAgY29uc3QgcmIgPSB1c2VSYigpOwogIGNvbnN0IFt3aWR0aCwgc2V0V2lkdGhdID0gdXNlU3RhdGUoMjApOwogIGNvbnN0IFtlbmFibGVkLCBzZXRFbmFibGVkXSA9IHVzZVN0YXRlKHRydWUpOwoKICByZXR1cm4gKAogICAgPGRpdiBjbGFzc05hbWU9ImZsZXggZmxleC1jb2wgZ2FwLTQiPgogICAgICA8UkJTbGlkZXIKICAgICAgICB2YWx1ZT17W3dpZHRoXX0KICAgICAgICBtaW49ezB9CiAgICAgICAgbWF4PXsxMDB9CiAgICAgICAgb25WYWx1ZUNoYW5nZT17KHZhbHVlczogbnVtYmVyW10pID0+IHNldFdpZHRoKHZhbHVlc1swXSA/PyAwKX0KICAgICAgLz4KICAgICAgPFJCU3dpdGNoIGNoZWNrZWQ9e2VuYWJsZWR9IG9uQ2hlY2tlZENoYW5nZT17c2V0RW5hYmxlZH0gLz4KICAgICAgPFJCTGFiZWxCdXR0b24KICAgICAgICBkaXNhYmxlZD17IWVuYWJsZWR9CiAgICAgICAgb25DbGljaz17KCkgPT4gcmIuYWN0aW9uKCJncmlwIiwgeyB3aWR0aCB9KX0KICAgICAgPgogICAgICAgIEdyaXAKICAgICAgPC9SQkxhYmVsQnV0dG9uPgogICAgPC9kaXY+CiAgKTsKfQpgYGAKCi0tLQoKIyMgRGV2ZWxvcGluZyBkaXJlY3RseSBvbiB0aGUgcm9ib3QgUEMKCklmIHlvdSdyZSBydW5uaW5nIGBtdXNjYXQtcGsgZGV2YCAqKm9uIHRoZSByb2JvdCBQQyBpdHNlbGYqKiwgTXVzY2F0IGFscmVhZHkgc2VydmVzIHRoZQpwbHVnaW4gZ2F0ZXdheSBvbiBwb3J0IDEwMDAwLiBUaGUgQ0xJIHNlZXMgdGhhdCwgZG9lcyBub3Qgc3RhcnQgaXRzIG93biBsb2NhbCBNdXNjYXQsIGFuZAp5b3VyIHBsdWdpbiBiYWNrZW5kIGNvbm5lY3RzIHRvIHRoZSByb2JvdCdzIGdhdGV3YXkg4oCUIGV4YWN0bHkgd2hhdCB5b3Ugd2FudCB3aGVuCmRldmVsb3Bpbmcgb24gdGhlIHJvYm90LgoKLS0tCgojIyBTZXZlcmFsIGRldmVsb3BlcnMgb24gb25lIHJvYm90CgpBZ2FpbnN0IGEgcmVtb3RlIHJvYm90LCBgbXVzY2F0LXBrIGRldmAgLyBgZGV2OmJhY2tgIHJ1biB5b3VyIHBsdWdpbiB1bmRlciBhIGRldiBpZCBvZiBpdHMgb3duLApgPG1hbmlmZXN0IGlkPi5kZXYtPHVzZXI+LTxyYW5kb20+YCAocHJpbnRlZCBhdCBzdGFydDsgdGhlIHJhbmRvbSBwYXJ0IGlzIGtlcHQgaW4gYH4vLm11c2NhdC1way9kZXYtaWRgKS4KVHdvIG1hY2hpbmVzIGRldmVsb3BpbmcgdGhlIHNhbWUgcGx1Z2luIG9uIG9uZSByb2JvdCB3b3VsZCBvdGhlcndpc2UgcmVnaXN0ZXIgdGhlIHNhbWUgdG9waWNzIG9uIGl0cwpnYXRld2F5LCBhbmQgYSBidXR0b24gaW4gb25lIFVJIHdvdWxkIHNpbGVudGx5IHJ1biB0aGUgb3RoZXIgbWFjaGluZSdzIGJhY2tlbmQuIFRoZSBVSSwgdGhlIGJhY2tlbmQsCnRoZSBST1MgbmFtZXNwYWNlIGFuZCBleHRlcm5hbCByb3V0ZXMgKGBjb21tb24vcGx1Z2luLzxkZXYgaWQ+LzxwYXRoPmApIGFsbCB1c2UgdGhlIGRldiBpZC4KClBhc3MgYC0ta2VlcC1pZGAgdG8gcnVuIHVuZGVyIHRoZSBtYW5pZmVzdCBpZCBpbnN0ZWFkLCBlLmcuIHRvIHRlc3QgcHJvZ3JhbSBgZXhlY3V0ZWAgb3IgYW4gZXh0ZXJuYWwKY2xpZW50IHRoYXQgdXNlcyB0aGUgcmVhbCBpZC4gVGhlbiBvbmx5IG9uZSBtYWNoaW5lIG1heSBiZSBjb25uZWN0ZWQgdG8gdGhhdCByb2JvdC4KCi0tLQoKIyMgQmFja2VuZCBydW50aW1lcwoKYG1hbmlmZXN0Lmpzb25gIGNob29zZXMgb25lIGJhY2tlbmQgcnVudGltZS4gYG11c2NhdC1wayBkZXZgIHJ1bnMgYmFja2VuZCBjb2RlIGluCmEgRG9ja2VyIGNvbnRhaW5lciBtYXRjaGluZyB0aGUgcm9ib3QgZW52aXJvbm1lbnQuIEJhY2tlbmQgY29kZSBzaG91bGQgY29udGFpbgpwbHVnaW4gbG9naWMgb25seTsgaXQgc2hvdWxkIG5vdCBzdGFydCBpdHMgb3duIGNvcHkgb2YgdGhlIHBsdWdpbiBnYXRld2F5LgoKIyMjIFdoaWNoIGJhY2tlbmQgcGF0dGVybj8gKGRlcGVuZHMgb24gdGhlIGNvbnRyaWJ1dGlvbiBwb2ludCkKCioqSG93IHlvdSBjb250cm9sIHRoZSByb2JvdCBkZXBlbmRzIG9uIHdoYXQgeW91ciBwbHVnaW4gY29udHJpYnV0ZXMqKiAoc2VlCmBtYW5pZmVzdC5qc29uYCDihpIgYGNvbnRyaWJ1dGVzW10ucG9pbnRgKS4gRG9uJ3QgbWl4IHRoZXNlIHVwOgoKfCBDb250cmlidXRpb24gcG9pbnQgfCBXaGF0IGl0IGlzIHwgQmFja2VuZCBwYXR0ZXJuIHwKfCAtLS0gfCAtLS0gfCAtLS0gfAp8IGBwcm9ncmFtLnBhbmVsYCAod2l0aCBgY29tbWFuZEluZm9gKSB8IERlZmluZXMgYSAqKmN1c3RvbSBjb21tYW5kKiogdGhlIHBsdWdpbiBhZGRzIHRvIHRoZSBQcm9ncmFtIHBhZ2UncyBydWxlLWJhc2VkIHNlcXVlbmNlIGJ1aWxkZXIuIFRoZSBvcGVyYXRvciBwbGFjZXMgaXQgaW50byB0aGUgcHJvZ3JhbSB0cmVlIGxpa2UgYW55IGJ1aWx0LWluIGNvbW1hbmQgKE1vdmUgSiwgUG9pbnQsIFdhaXQsIOKApik7IGl0IHJ1bnMgd2hlbiB0aGUgcHJvZ3JhbSByZWFjaGVzIHRoYXQgc3RlcC4gfCAqKmBQbHVnaW5Qcm9ncmFtQ29udGV4dGAqKiDigJQgaW50ZWdyYXRlZCB3aXRoIHRoZSBwcm9ncmFtJ3Mgc3RvcC9wYXVzZSBhbmQgdmFyaWFibGVzLiBTZWUgX1Byb2dyYW0gY29tbWFuZCBiYWNrZW5kXyBiZWxvdy4gfAp8IGB0b29sYmFyYCAvIGBsbmJgIC8gYG1vdmUucGFuZWxgIHwgQSBsaXZlIFVJIHBhbmVsL3BvcG92ZXIgdGhlIG9wZXJhdG9yIGludGVyYWN0cyB3aXRoIGRpcmVjdGx5IHwgQ2FsbCB0aGUgcm9ib3QgKipTREsgZGlyZWN0bHkqKiAoYFJCTWFuaXB1bGF0ZVNES2AsIGBSQkFtclNES2ApIGZyb20gYHB5L21haW4ucHlgLCBvciBgcmIuYWN0aW9uKC4uLilgIOKGkiB5b3VyIGJhY2tlbmQg4oaSIFNESy4gKipOb3QqKiBhIHByb2dyYW0gc3RlcCDigJQgdGhlcmUgaXMgbm8gc3RvcC9wYXVzZS92YXJpYWJsZSBjb250ZXh0LiB8CgpSdWxlIG9mIHRodW1iOiB1c2UgYFBsdWdpblByb2dyYW1Db250ZXh0YCAqKm9ubHkqKiBmb3IgYSBgcHJvZ3JhbS5wYW5lbGAgY29tbWFuZAp0aGF0IHJ1bnMgYXMgcGFydCBvZiBhIHByb2dyYW0uIFRvIG1vdmUgdGhlIHJvYm90IGxpdmUgZnJvbSBhIHRvb2xiYXIvbW92ZSBwYW5lbCwKdXNlIHRoZSBTREsg4oCUIGEgcHJvZ3JhbS1zdGVwIGNvbnRleHQgZG9lcyBub3QgYXBwbHkuCgojIyMgRnJvbnRlbmQtb25seSAoYG5vbmVgKQoKVXNlIHRoaXMgd2hlbiB0aGUgcGx1Z2luIG9ubHkgaGFzIFVJIGFuZCBjYWxscyBob3N0IHNlcnZpY2VzOgoKYGBganNvbgp7ICJydW50aW1lIjogeyAidHlwZSI6ICJub25lIiB9IH0KYGBgCgojIyMgUHl0aG9uCgpQeXRob24gcGx1Z2lucyB1c2UgYHB5L21haW4ucHlgIGFuZCBjYW4gY29tbXVuaWNhdGUgd2l0aCB0aGUgVUkgdGhyb3VnaApgcmFpbmJvdy5yYl9zZGsuUkJQbHVnaW5DYWxsYC4KCmBgYHB5dGhvbgppbXBvcnQgdGltZQpmcm9tIHJhaW5ib3cucmJfc2RrIGltcG9ydCBSQkFtclNESywgUkJNYW5pcHVsYXRlU0RLLCBSQlBsdWdpbkNhbGwKCnBsdWdpbiA9IFJCUGx1Z2luQ2FsbCgpCgoKcGx1Z2luLnB1Ymxpc2goInN0YXRlIiwgeyJyZWFkeSI6IFRydWV9KQoKCkBwbHVnaW4uc3Vic2NyaWJlKCJldmVudCIpCmRlZiBvbl91aV9ldmVudChwYXlsb2FkPU5vbmUpOgogICAgcHJpbnQocGF5bG9hZCkKCgpAcGx1Z2luLnNlcnZlKCJ0b29sL2VjaG8iKQpkZWYgZWNobyhwYXlsb2FkPU5vbmUpOgogICAgcmV0dXJuIHsiZWNobyI6IHBheWxvYWR9CgoKZGVmIGNhbGxfZnJvbnRlbmQoKToKICAgIHJlcyA9IHBsdWdpbi5jYWxsKCJ0b29sL3BpbmciLCBwYXlsb2FkPXsiaGVsbG8iOiAicGx1Z2luIn0pCiAgICBwcmludChyZXMpCgoKZGVmIG1vdmVfal9leGFtcGxlKCk6CiAgICBhbXIgPSBSQkFtclNESygpCiAgICBtYW5pcHVsYXRlID0gUkJNYW5pcHVsYXRlU0RLKCkKICAgIHJldHVybiBtYW5pcHVsYXRlLm1vdmUuY2FsbF9tb3ZlX2ooCiAgICAgICAgcm9ib3RfbW9kZWw9IkM1MDA5MjAiLAogICAgICAgIHRhcmdldD17InRhcl92YWx1ZXMiOiBbMCwgMCwgMCwgMCwgMCwgMCwgMF0sICJ0YXJfZnJhbWUiOiAtMSwgInRhcl91bml0IjogMH0sCiAgICApCgoKaWYgX19uYW1lX18gPT0gIl9fbWFpbl9fIjoKICAgIHdoaWxlIFRydWU6CiAgICAgICAgdGltZS5zbGVlcCgxKQpgYGAKCiMjIyMgRXh0ZXJuYWwgZW5kcG9pbnRzIChgcGx1Z2luLnJvdXRlcmApCgpgcGx1Z2luLnNlcnZlYCAvIGBwbHVnaW4uc3Vic2NyaWJlYCAvIGBwbHVnaW4ucHVibGlzaGAgYXJlICoqaW50ZXJuYWwgb25seSoqIChwbHVnaW4KVUkg4oaUIGJhY2tlbmQsIHBsdWdpbiDihpQgcGx1Z2luKS4gVG8gZXhwb3NlIGFuIGVuZHBvaW50IHRvIHRoZSBvdXRzaWRlIHdvcmxkIOKAlApSRVNULCBTb2NrZXQuSU8sIFRDUCwgTVFUVCwgV2ViUlRDIOKAlCB1c2UgYHBsdWdpbi5yb3V0ZXJgLiBEZWNsYXJpbmcgb25lIGlzIGEKc2luZ2xlIGRlY29yYXRvcjsgdGhlIHJ1bm5pbmcgTXVzY2F0IChgY29tbW9uYCkgcGlja3MgaXQgdXAgd2l0aG91dCBhIHJlc3RhcnQsCmFuZCBpdCBkaXNhcHBlYXJzIHdoZW4gdGhlIHBsdWdpbiBzdG9wcyBvciBpcyByZW1vdmVkLgoKPiBSZXF1aXJlcyBhIHJvYm90IHJ1bm5pbmcgYHJhaW5ib3ctcmItc2RrYCAqKjAuMC45LmRldjUgb3IgbmV3ZXIqKiAodGhlIFNESyBpcwo+IHByb3ZpZGVkIGJ5IHRoZSBwbHVnaW4gY29udGFpbmVyIGF0IHJ1bnRpbWUpLiBPbiBvbGRlciByb2JvdHMgYHBsdWdpbi5yb3V0ZXJgCj4gZG9lcyBub3QgZXhpc3QgYW5kIHJhaXNlcyBgQXR0cmlidXRlRXJyb3JgLgoKYGBgcHl0aG9uCmZyb20gcmFpbmJvdy5yYl9zZGsgaW1wb3J0IFJCUGx1Z2luQ2FsbApmcm9tIHJhaW5ib3cucmJfc2RrLnBsdWdpbiBpbXBvcnQgUGx1Z2luUm91dGVFcnJvcgoKcGx1Z2luID0gUkJQbHVnaW5DYWxsKCkgICMgcGx1Z2luX2lkIGNvbWVzIGZyb20gZW52IFJCX1BMVUdJTl9JRAoKCkBwbHVnaW4ucm91dGVyLm9uKCIvaGVsbG8iKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGFsbCA1IHRyYW5zcG9ydHMKZGVmIGhlbGxvKHBheWxvYWQ6IGRpY3QsIG1ldGE6IGRpY3QpOgogICAgcmV0dXJuIHsibXNnIjogZiJoaSB7cGF5bG9hZC5nZXQoJ25hbWUnKX0ifSAgICAgICAgICAgICAgIyByZXR1cm4gdmFsdWUgPSByZXNwb25zZSBib2R5CgoKQHBsdWdpbi5yb3V0ZXIub24oIi9hZG1pbiIsIGV4cGxpY2l0X3JvdXRlcz1bImFwaSJdKSAgICAgICAgICMgUkVTVCBvbmx5CmRlZiBhZG1pbihwYXlsb2FkLCBtZXRhKToKICAgIGlmIG5vdCAobWV0YS5nZXQoInByaW5jaXBhbCIpIG9yIHt9KS5nZXQoImlzX2FkbWluIik6CiAgICAgICAgcmFpc2UgUGx1Z2luUm91dGVFcnJvcig0MDMsICJhZG1pbiBvbmx5IikgICAgICAgICAgICAjIGJlY29tZXMgdGhlIGV4dGVybmFsIHN0YXR1cwogICAgLi4uCgoKQHBsdWdpbi5yb3V0ZXIuc3Vic2NyaWJlKCIvY21kIiwgZXhwbGljaXRfZXZlbnRzPVsidGNwIl0pICAgICMgcmVjZWl2ZSBleHRlcm5hbCBUQ1AgcHVibGlzaApkZWYgb25fY21kKHBheWxvYWQ6IGRpY3QpOgogICAgLi4uCgoKcGx1Z2luLnJvdXRlci5lbWl0KCIvc3RhdGUiLCB7ImJ1c3kiOiBUcnVlfSkgICAgICAgICAgICAgICAgICMgcHVzaCB0byBleHRlcm5hbCBzdWJzY3JpYmVycwpgYGAKCnwgQVBJIHwgTWVhbmluZyB8IEV4dGVybmFsIGFkZHJlc3MgfAp8IC0tLSB8IC0tLSB8IC0tLSB8CnwgYHJvdXRlci5vbihwYXRoLCBleHBsaWNpdF9yb3V0ZXM9Tm9uZSlgIHwgcmVxdWVzdC9yZXNwb25zZSBoYW5kbGVyIHwgYGNvbW1vbi9wbHVnaW4ve3BsdWdpbl9pZH0ve3BhdGh9YCAoUkVTVCBpcyBhbHdheXMgYFBPU1RgKSB8CnwgYHJvdXRlci5zdWJzY3JpYmUodG9waWMsIGV4cGxpY2l0X2V2ZW50cz1Ob25lKWAgfCByZWNlaXZlIGV4dGVybmFsIHB1Ymxpc2hlcyB8IGV4dGVybmFsIHNpZGUgcHVibGlzaGVzIHRvIGBjb21tb24vcGx1Z2luL3twbHVnaW5faWR9L3t0b3BpY31gIHwKfCBgcm91dGVyLmVtaXQodG9waWMsIHBheWxvYWQpYCB8IHBsdWdpbiDihpIgZXh0ZXJuYWwgcHVzaCB8IGV4dGVybmFsIHNpZGUgc3Vic2NyaWJlcyB0byBgY29tbW9uL3BsdWdpbi97cGx1Z2luX2lkfS97dG9waWN9YCB8CgotIFRoZSBgcGx1Z2luX2lkYCBwcmVmaXggaXMgYWRkZWQgYnkgdGhlIFNESyDigJQgd3JpdGUgb25seSB0aGUgcGF0aCBpbiBwbHVnaW4gY29kZS4KLSBQYXRocyBtYXkgaGF2ZSBzZXZlcmFsIHNlZ21lbnRzIChgL3Rvb2wvZWNob2ApLiBEZWNsYXJpbmcgdGhlIHNhbWUgcGF0aCB0d2ljZSByYWlzZXMgYFZhbHVlRXJyb3JgLgotIFRyYW5zcG9ydCBuYW1lczogYGFwaSB8IHNvY2tldCB8IHRjcCB8IG1xdHQgfCB3ZWJydGNgLiBgc3Vic2NyaWJlYCBhY2NlcHRzIG9ubHkgYHRjcCB8IG1xdHQgfCB3ZWJydGNgLiBVbmtub3duIG5hbWVzIHJhaXNlIGBWYWx1ZUVycm9yYC4KLSBgZXhwbGljaXRfcm91dGVzYCAvIGBleHBsaWNpdF9ldmVudHNgIG9mIGBOb25lYCBtZWFucyBldmVyeSB0cmFuc3BvcnQuIEEgcmVxdWVzdCBvbiBhIHRyYW5zcG9ydCBub3QgbGlzdGVkIGdldHMgNDA0LgoKSGFuZGxlciBjb250cmFjdDoKCi0gU2lnbmF0dXJlIGAocGF5bG9hZCwgbWV0YSlgLCBgKHBheWxvYWQpYCBvciBgKClgIOKAlCBvbmx5IHRoZSBhcmd1bWVudHMgeW91IGRlY2xhcmUgYXJlIGluamVjdGVkLiBTeW5jIGFuZCBhc3luYyBib3RoIHdvcmsuCi0gYHBheWxvYWRgOiB3aGF0IHRoZSBjYWxsZXIgc2VudCAoZm9yIFJFU1Q6IEpTT04gYm9keSBtZXJnZWQgd2l0aCBxdWVyeSBwYXJhbXMpLiBUaGUgc2hhcGUgaXMgdXAgdG8gdGhlIHBsdWdpbi4KLSBgbWV0YWA6IGB7InRyYW5zcG9ydCI6ICJhcGkifCJzb2NrZXQifCJ0Y3AifCJtcXR0Inwid2VicnRjIiwgInByaW5jaXBhbCI6IGRpY3QgfCBOb25lfWAuIFdoZW4gdGhlIHJvYm90J3MgbG9naW4gcG9saWN5IGlzIG9uLCBgcHJpbmNpcGFsYCBob2xkcyB0aGUgdG9rZW4gc3ViamVjdC4gKipSb2xlIGNoZWNrcyBhcmUgdGhlIHBsdWdpbidzIGpvYioqIOKAlCBpbnNwZWN0IGBtZXRhWyJwcmluY2lwYWwiXWAgeW91cnNlbGYuCi0gVGhlIHJldHVybiB2YWx1ZSBpcyB0aGUgcmVzcG9uc2UgYm9keSAobXVzdCBiZSBKU09OLXNlcmlhbGlzYWJsZSkuIGBOb25lYCDihpIgZW1wdHkgcmVzcG9uc2UuCi0gU3RhdHVzIGNvZGVzOiBgcmFpc2UgUGx1Z2luUm91dGVFcnJvcihjb2RlLCBtZXNzYWdlKWAuIEFueSBvdGhlciBleGNlcHRpb24g4oaSIDUwMCB3aXRoIGBzdHIoZXhjKWAgYXMgdGhlIG1lc3NhZ2UuCi0gYHN1YnNjcmliZWAgaGFuZGxlcnMgdGFrZSBgKHBheWxvYWQpYCBvbmx5IGFuZCByZXR1cm4gbm90aGluZy4KCiMjIyMgQ2FsbGluZyBwbHVnaW4gZW5kcG9pbnRzIGZyb20gb3V0c2lkZQoKfCBUcmFuc3BvcnQgfCBIb3cgfAp8IC0tLSB8IC0tLSB8CnwgUkVTVCB8IGBQT1NUIC9jb21tb24vcGx1Z2luL3twbHVnaW5faWR9L3twYXRofWAgKHRocm91Z2ggdGhlIGFwaS1nYXRld2F5KSwgSlNPTiBib2R5IHwKfCBTb2NrZXQuSU8gfCBlbWl0IGV2ZW50IGBjb21tb24vcGx1Z2luL3twbHVnaW5faWR9L3twYXRofWAsIHJlc3BvbnNlIGFycml2ZXMgaW4gdGhlIGFjayB8CnwgVENQIHwgdG9waWMgYGNvbW1vbi9wbHVnaW4ve3BsdWdpbl9pZH0ve3BhdGh9YCByZXF1ZXN0IC8gcHVibGlzaCB8CnwgTVFUVCB8IHJlcXVlc3Q6IGBjb21tb24vcGx1Z2luL3twbHVnaW5faWR9L3twYXRofS9fX3JlcV9fYCwgcHVibGlzaDogYGNvbW1vbi9wbHVnaW4ve3BsdWdpbl9pZH0ve3RvcGljfWAgfAp8IFdlYlJUQyB8IGRhdGEgY2hhbm5lbCB0b3BpYyBgY29tbW9uL3BsdWdpbi97cGx1Z2luX2lkfS97cGF0aH1gIHwKCkF1dGg6IHdoZW4gdGhlIHJvYm90J3MgbG9naW4gcG9saWN5IGlzIG9uLCBhIHRva2VuIGlzICoqcmVxdWlyZWQqKiAoYW55IHJvbGUg4oCUIEdVRVNUIHBhc3NlcykuIFdoZW4gaXQgaXMgb2ZmLCBjYWxscyBnbyBzdHJhaWdodCB0aHJvdWdoLiBSRVNUIHVzZXMgdGhlIHNhbWUgQmVhcmVyIHRva2VuIGFzIHRoZSBvdGhlciBNdXNjYXQgQVBJcy4KCmBgYGJhc2gKY3VybCAtcyAtWCBQT1NUIGh0dHA6Ly88cm9ib3Q+L2NvbW1vbi9wbHVnaW4vbXktcGx1Z2luL2hlbGxvIFwKICAtSCAnQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9qc29uJyAtZCAneyJuYW1lIjoia2ltIn0nCmBgYAoKfCBTaXR1YXRpb24gfCBTdGF0dXMgfAp8IC0tLSB8IC0tLSB8CnwgTm8gcGx1Z2luIGRlY2xhcmVzIHRoYXQgcGF0aCAvIHBsdWdpbiBpcyBkb3duIC8gdHJhbnNwb3J0IG5vdCBhbGxvd2VkIHwgNDA0IHwKfCBQbHVnaW4gZGlkIG5vdCBhbnN3ZXIgd2l0aGluIDEwIHMgfCA1MDQgfAp8IGBjb21tb25gIOKGlCBnYXRld2F5IG5vdCBjb25uZWN0ZWQgfCA1MDMgfAp8IEhhbmRsZXIgcmFpc2VkIHwgNTAwIChgUGx1Z2luUm91dGVFcnJvcmAg4oaSIGl0cyBgY29kZWApIHwKCktub3duIGxpbWl0czoKCi0gQSBwbHVnaW4gcGF0aCBuYW1lZCBgaW5zdGFsbGAgY2Fubm90IGJlIGNhbGxlZCBvdmVyIFJFU1QgKGBQT1NUIC9jb21tb24vcGx1Z2luL3tpZH0vaW5zdGFsbGAgaXMgdGFrZW4gYnkgdGhlIHJlZ2lzdHJ5IGluc3RhbGwgcm91dGUgZmlyc3QpLiBTb2NrZXQvVENQIGFyZSB1bmFmZmVjdGVkLgotIFN3YWdnZXIgc2hvd3Mgb25lIGNhdGNoLWFsbCByb3V0ZSwgbm90IHBlci1wbHVnaW4gcGF0aHMuCi0gVGhlIE1RVFQgYnJva2VyIGVjaG9lcyB0byB0aGUgc2VuZGVyOiBhIHBsdWdpbiB0aGF0IGBlbWl0YHMgYW5kIGBzdWJzY3JpYmVgcyB0aGUgc2FtZSB0b3BpYyByZWNlaXZlcyBpdHMgb3duIHB1c2ggb3ZlciBgbXF0dGAuIERyb3AgYG1xdHRgIGZyb20gYGV4cGxpY2l0X2V2ZW50c2Agb3IgdXNlIHNlcGFyYXRlIHRvcGljcy4gKFRDUCBpcyBmaWx0ZXJlZCBieSBgc2VuZGVyX2lkYC4pCi0gYG9uYCBhbmQgYHN1YnNjcmliZWAgbWF5IHNoYXJlIGEgbmFtZSDigJQgdGhleSBsaXZlIGluIHNlcGFyYXRlIHRhYmxlcy4KCkR1cmluZyBgbXVzY2F0LXBrIGRldmAgdGhlIGxvY2FsIE11c2NhdCBydW50aW1lIHRha2VzIHRoZSBgcm91dGVyLipgIHJlZ2lzdHJhdGlvbnMKb24gaXRzIGdhdGV3YXkgKHBvcnQgYDEwMDAwYCksIGFuZCBpdHMgYGNvbW1vbmAgKHBvcnQgYDMwMDBgKSByb3V0ZXMKYGNvbW1vbi9wbHVnaW4vLi4uYCB0byB0aGVtIGxpa2Ugb24gdGhlIHJvYm90IOKAlCB0cnkKYGN1cmwgaHR0cDovL2xvY2FsaG9zdDozMDAwL2NvbW1vbi9wbHVnaW4vPHBsdWdpbi1pZD4vPHBhdGg+YC4gQWZ0ZXIgcmVzdGFydGluZyB0aGUgcGx1Z2luIHByb2Nlc3MsCmV4dGVybmFsIGNhbGxzIG1heSByZXR1cm4gNTA0IGZvciB1cCB0byBhYm91dCBhIG1pbnV0ZSAodW50aWwgdGhlIGdhdGV3YXkgbm90aWNlcwp0aGUgb2xkIHNvY2tldCBpcyBnb25lKSwgdGhlbiA0MDQg4oCUIHRoYXQgaXMgZXhwZWN0ZWQuCgojIyMjIFByb2dyYW0gY29tbWFuZCBiYWNrZW5kIChgcHJvZ3JhbS5wYW5lbGApCgpBIGBwcm9ncmFtLnBhbmVsYCBjb250cmlidXRpb24gZGVmaW5lcyBhICoqY3VzdG9tIGNvbW1hbmQqKiB5b3VyIHBsdWdpbiBhZGRzIHRvCnRoZSBNdXNjYXQgKipQcm9ncmFtIHBhZ2UqKiwgd2hlcmUgdGhlIG9wZXJhdG9yIGJ1aWxkcyBhIHJvYm90IHByb2dyYW0gYXMgYQpydWxlLWJhc2VkIHNlcXVlbmNlIChhIHByb2dyYW0gdHJlZSkuIFlvdXIgY29tbWFuZCBhcHBlYXJzIGFsb25nc2lkZSB0aGUKYnVpbHQtaW5zIChNb3ZlIEosIFBvaW50LCBXYWl0LCDigKYpOyB0aGUgb3BlcmF0b3IgcGxhY2VzIGl0IGludG8gdGhlIHRyZWUsIGFuZAplYWNoIHRpbWUgdGhlIHByb2dyYW0gZXhlY3V0ZXMgdGhhdCBzdGVwIHRoZSBob3N0IGNhbGxzIHlvdXIgYmFja2VuZCB0aHJvdWdoCmBQbHVnaW5Qcm9ncmFtQ29udGV4dGAg4oCUIHJlY2VpdmluZyB0aGUgc3RlcCBhcmdzLCBjaGVja2luZyBmb3Igc3RvcC9wYXVzZSwKcmVhZGluZy93cml0aW5nIHByb2dyYW0gdmFyaWFibGVzLCBhbmQgc2lnbmFsbGluZyBjb21wbGV0aW9uLiBUaGlzIHBhdHRlcm4gaXMKKipvbmx5KiogZm9yIGBwcm9ncmFtLnBhbmVsYDsgYSB0b29sYmFyL21vdmUtcGFuZWwgcGx1Z2luIHVzZXMgdGhlIFNESyBkaXJlY3RseQppbnN0ZWFkIChzZWUgdGhlIHRhYmxlIGFib3ZlKS4KCmBgYHB5dGhvbgoiIiIKUGx1Z2luIGJhY2tlbmQgbWFpbi5weSBleGFtcGxlIChwcm9ncmFtLnBhbmVsIGNvbW1hbmQpLgoKbWFuaWZlc3QuanNvbjoKICAicnVudGltZSI6IHsidHlwZSI6ICJweXRob24iLCAiZW50cnkiOiAibWFpbi5weSJ9LAogICJjb250cmlidXRlcyI6IFt7CiAgICAicG9pbnQiOiAicHJvZ3JhbS5wYW5lbCIsCiAgICAidWkiOiAicHJvZ3JhbSIsCiAgICAibGFiZWwiOiB7ImVuIjogIk15IFBsdWdpbiBTdGVwIn0sCiAgICAiY29tbWFuZEluZm8iOiB7CiAgICAgICJuYW1lIjogIk15IFBsdWdpbiBTdGVwIiwKICAgICAgImljb24iOiAiYXNzZXRzL2ljb24uc3ZnIiwKICAgICAgImZ1bmNOYW1lIjogInJiX3Byb2dyYW1fc2RrLnBsdWdpbl9leGVjdXRlIiwKICAgICAgImFyZ3MiOiB7Im1lc3NhZ2UiOiAiaGVsbG8ifSAgICMgcGx1Z2luLWF1dGhvci1kZWZpbmVkIGFyZ3MKICAgIH0KICB9XQoKVGhlIGhvc3QgaW52b2tlcyBjb21tYW5kSW5mby5mdW5jTmFtZSAocmJfcHJvZ3JhbV9zZGsucGx1Z2luX2V4ZWN1dGUpIHdpdGgKYXJncy5wbHVnaW5faWQgKyB5b3VyIGFyZ3Mgd2hlbiB0aGUgcHJvZ3JhbSByZWFjaGVzIHRoaXMgc3RlcC4KIiIiCmltcG9ydCBhc3luY2lvCmZyb20gcmFpbmJvdy5yYl9zZGsgaW1wb3J0IFBsdWdpblByb2dyYW1Db250ZXh0CgpjdHggPSBQbHVnaW5Qcm9ncmFtQ29udGV4dChwbHVnaW5faWQ9Im15LXBsdWdpbiIpCgoKQGN0eC5vbl9leGVjdXRlCmFzeW5jIGRlZiBoYW5kbGUoYXJnczogZGljdCkgLT4gTm9uZToKICAgICIiIkNhbGxlZCBvbmNlIHdoZW4gbXkgU3RlcCBleGVjdXRlcy4gVmFyaWFibGUgd3JpdGVzIGFwcGx5IHRvIHRoZQogICAgcnVubmluZyBwcm9ncmFtIGltbWVkaWF0ZWx5ICsgYnJvYWRjYXN0IHRvIG90aGVyIHJvYm90cycgbWFpbiB0YXNrcy4iIiIKICAgIGNvdW50ID0gYXdhaXQgY3R4LmdldF92YXJpYWJsZSgiY291bnRlciIpICAgICAgICAgICMgcmVhZCBhbiBleGlzdGluZyBwcm9ncmFtIHZhcmlhYmxlCiAgICBhd2FpdCBjdHguc2V0X3ZhcmlhYmxlKCJjb3VudGVyIiwgY291bnQgKyAxKSAgICAgICAjIHVwZGF0ZSBhbiBleGlzdGluZyB2YXJpYWJsZSDigJQgYWxsb3dlZAogICAgYXdhaXQgY3R4LnNldF92YXJpYWJsZSgiUkJQX1RFU1QiLCAxKSAgICAgICAgICAgICAgIyBORVcgdmFyaWFibGVzIG11c3Qgc3RhcnQgd2l0aCBSQlBfCgogICAgZm9yIGkgaW4gcmFuZ2UoMTAwKToKICAgICAgICBhd2FpdCBjdHguY2hlY2tfc3RvcCgpICAgIyBhdXRvLXNjb3BlZCB0byB0aGlzIFN0ZXAncyByb2JvdCBtb2RlbAogICAgICAgIGF3YWl0IGFzeW5jaW8uc2xlZXAoMC41KQoKICAgIGF3YWl0IGN0eC5kb25lKCkKCgphc3luYyBkZWYgYmFja2dyb3VuZF9tb25pdG9yKCkgLT4gTm9uZToKICAgICIiIlJlc2lkZW50IHRhc2sgb3V0c2lkZSBhbnkgU3RlcC4gSWYgbm8gcHJvZ3JhbSBpcyBydW5uaW5nLAogICAgZ2V0IHJldHVybnMgTm9uZSBhbmQgc2V0IGlzIHNpbGVudGx5IGlnbm9yZWQg4oCUIGFsd2F5cyBzYWZlIHRvIGNhbGwuIiIiCiAgICB3aGlsZSBUcnVlOgogICAgICAgIGF3YWl0IGFzeW5jaW8uc2xlZXAoMS4wKQoKICAgICAgICAjIHRhcmdldHMgZXZlcnkgcnVubmluZyBtYWluIHRhc2sgKG5vIHJvYm90X21vZGVsIHBhcmFtIOKAlCBhbHdheXMgYnJvYWRjYXN0KQogICAgICAgIGF3YWl0IGN0eC5zZXRfdmFyaWFibGUoIlJCUF9URVNUIiwgMykKCiAgICAgICAgIyBnZXQgb3B0aW9ucwogICAgICAgIHYxID0gYXdhaXQgY3R4LmdldF92YXJpYWJsZSgiY291bnRlciIpICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBmaXJzdCB2YWx1ZSBmb3VuZCBpbiB0aGUgd2hvbGUgdHJlZQogICAgICAgIHYyID0gYXdhaXQgY3R4LmdldF92YXJpYWJsZSgiY291bnRlciIsIHJvYm90X21vZGVsPSJDNTAwOTIwIikgICAgIyBhIHNwZWNpZmljIHJvYm90CiAgICAgICAgdjMgPSBhd2FpdCBjdHguZ2V0X3ZhcmlhYmxlKCJSQlBfVEVTVCIsIHBsdWdpbl9pZD0ibXktcGx1Z2luIikgICAjIHRoZSB2YWx1ZSBteS1wbHVnaW4gbGFzdCB3cm90ZQoKICAgICAgICBpZiBjdHguZXhlY3V0b3Jfc3RhdGUoIkM1MDA5MjAiKSA9PSAicGF1c2VkIjoKICAgICAgICAgICAgcHJpbnQoIkM1MDA5MjAgcHJvZ3JhbSBpcyBwYXVzZWQiKQoKCmFzeW5jIGRlZiBtYWluKCkgLT4gTm9uZToKICAgIGFzeW5jaW8uY3JlYXRlX3Rhc2soYmFja2dyb3VuZF9tb25pdG9yKCkpCiAgICBhd2FpdCBjdHguc3RhcnQoKSAgIyBzdGF5cyByZXNpZGVudAoKCmFzeW5jaW8ucnVuKG1haW4oKSkKYGBgCgojIyMjIFByb2dyYW0gdmFyaWFibGVzICYgZXhlY3V0b3Igc3RhdGUgKGBQbHVnaW5Qcm9ncmFtQ29udGV4dGApCgpgcmFpbmJvdy5yYl9zZGsuUGx1Z2luUHJvZ3JhbUNvbnRleHRgIGxldHMgdGhlIHBsdWdpbiBwcm9jZXNzIGludGVyYWN0IHdpdGggdGhlCnJ1bm5pbmcgcHJvZ3JhbSAoUHlGTSk6IHJlYWQvd3JpdGUgcHJvZ3JhbSB2YXJpYWJsZXMgYW5kIG9ic2VydmUgZXhlY3V0aW9uCnN0YXRlIOKAlCBpbnNpZGUgYSBTdGVwIGhhbmRsZXIgb3IgZnJvbSBhIHJlc2lkZW50IHRhc2ssIGF0IGFueSB0aW1lLgoKLSBUaGUgYG9uX2V4ZWN1dGVgIGhhbmRsZXIgaXMgY2FsbGVkICoqb25seSB3aGVuIFB5Rk0gZXhlY3V0ZXMgdGhpcyBwbHVnaW4ncwogIFN0ZXAqKi4gT25lIFN0ZXAgZXhlY3V0aW9uID0gb25lIGhhbmRsZXIgY2FsbCwgYW5kIHRoZSBTdGVwIGRvZXMgbm90IGZpbmlzaAogIHVudGlsIHlvdSBjYWxsIGBjdHguZG9uZSgpYCDigJQgYWx3YXlzIGNhbGwgaXQuCi0gVGhlIHBsdWdpbiBwcm9jZXNzIGl0c2VsZiBzdGF5cyByZXNpZGVudCBhZnRlciBgY3R4LnN0YXJ0KClgOyBleGVjdXRvciBzdGF0ZQogIHF1ZXJpZXMgYW5kIHZhcmlhYmxlIGFjY2VzcyBiZWxvdyBrZWVwIHdvcmtpbmcgd2hldGhlciBvciBub3QgYSBTdGVwIGlzCiAgZXhlY3V0aW5nLgoKIyMjIyBWYXJpYWJsZSBuYW1pbmcgcnVsZXMgKGltcG9ydGFudCkKClB5Rk0gdmFyaWFibGVzIGFyZSBhICoqcHJvZ3JhbS13aWRlIHNoYXJlZCBuYW1lc3BhY2UqKi4gT25lIHJ1bGU6CgotICoqTW9kaWZ5aW5nIGFuIGV4aXN0aW5nIHZhcmlhYmxlKiog4oCUIHRoZSBuYW1lIHBhc3NlcyBhcy1pcy4gRXhjaGFuZ2luZwogIHZhcmlhYmxlcyBiZXR3ZWVuIHRoZSBwcm9ncmFtIGFuZCB0aGUgcGx1Z2luIGlzIHRoZSBpbnRlbmRlZCB1c2FnZS4KLSAqKkNyZWF0aW5nIGEgdmFyaWFibGUgdGhhdCBkb2Vzbid0IGV4aXN0Kiog4oCUIHRoZSBgUkJQX2AgcHJlZml4IGlzCiAgKipyZXF1aXJlZCoqIChlbmZvcmNlZCBieSB0aGUgU0RLL3NlcnZlcjsgYSB2aW9sYXRpb24gcmFpc2VzCiAgYFJ1bnRpbWVFcnJvcmApLiBBcHBsaWVzIGVxdWFsbHkgaW5zaWRlIGFuZCBvdXRzaWRlIFN0ZXAgZXhlY3V0aW9uLgoKRm9yIG5ldyB2YXJpYWJsZSBuYW1lcywgYSBjb252ZW50aW9uIHRoYXQgaW5jbHVkZXMgdGhlIHBsdWdpbiBpZCBpcyBzdHJvbmdseQpyZWNvbW1lbmRlZDoKCmBgYApSQlBfe3BsdWdpbl9pZH1fe25hbWV9CgplLmcuIFJCUF92aXNpb25fZGV0ZWN0X2NvdW50LCBSQlBfZ3JpcHBlcl9sYXN0X2Vycm9yCmBgYAoKV2h5OgoKLSBgUkJQX2Ag4oCUIGluc3RhbnRseSBpZGVudGlmaWVzIHBsdWdpbi1jcmVhdGVkIHZhcmlhYmxlcyBpbiB0aGUgcHJvZ3JhbQogIGVkaXRvci9VSS4KLSBge3BsdWdpbl9pZH1gIOKAlCAqKnByZXZlbnRzIG5hbWUgY29sbGlzaW9ucyB3aXRoIG90aGVyIHBsdWdpbnMuKiogSWYgdHdvCiAgcGx1Z2lucyB1c2UgdGhlIHNhbWUgbmFtZSB0aGV5IG92ZXJ3cml0ZSB0aGUgc2FtZSB2YXJpYWJsZSAoYFJCUF9gIGFsb25lIGlzCiAgbm90IHNvbWV0aGluZyB0aGUgU0RLIGd1YXJkcyBhZ2FpbnN0KS4KCiMjIyMgUmVhZGluZyAvIHdyaXRpbmcgdmFyaWFibGVzCgpgYGBweXRob24KdmFsdWUgPSBhd2FpdCBjdHguZ2V0X3ZhcmlhYmxlKCJjb3VudGVyIikgICAgICAgICAgICAgICAgICMgcmVhZCAobm8gbmFtZSByZXN0cmljdGlvbikKYXdhaXQgY3R4LnNldF92YXJpYWJsZSgiY291bnRlciIsIHZhbHVlICsgMSkgICAgICAgICAgICAgICMgbW9kaWZ5IGV4aXN0aW5nIHZhcmlhYmxlIOKAlCBhbGxvd2VkCmF3YWl0IGN0eC5zZXRfdmFyaWFibGUoIlJCUF9teS1wbHVnaW5fcmVzdWx0IiwgNDIpICAgICAgICAjIGNyZWF0ZSBuZXcgdmFyaWFibGUg4oCUIFJCUF8gcmVxdWlyZWQKYGBgCgpgc2V0X3ZhcmlhYmxlYCBhbHdheXMgYXBwbGllcyB0byAqKmV2ZXJ5IHJ1bm5pbmcgbWFpbiB0YXNrKiogKGEgcGx1Z2luIGJlbG9uZ3MKdG8gbXVzY2F0LCBub3QgdG8gYSBzcGVjaWZpYyByb2JvdCDigJQgdGhlcmUgaXMgbm8gYHJvYm90X21vZGVsYCBwYXJhbWV0ZXIpOgoKfCBXaGVuIHwgT3duIHByb2dyYW0gfCBPdGhlciByb2JvdHMnIG1haW4gdGFza3MgfAp8LS0tfC0tLXwtLS18CnwgRHVyaW5nIG93biBTdGVwIGV4ZWN1dGlvbiB8IHZpYSB0aGUgY29udHJvbCBxdWVyeWFibGUg4oCUICoqaW1tZWRpYXRlKiogfCBicm9hZGNhc3Qg4oCUIGVhY2ggYXQgaXRzIG5leHQgU3RlcCBib3VuZGFyeSB8CnwgT3V0c2lkZSBhIFN0ZXAgKHJlc2lkZW50IHRhc2ssIOKApikgfCByZXNpZGVudCBlbmRwb2ludCDigJQgbmV4dCBTdGVwIGJvdW5kYXJ5IHwgc2FtZSB8CgpgZ2V0X3ZhcmlhYmxlYCBoYXMgb3B0aW9uczoKCmBgYHB5dGhvbgphd2FpdCBjdHguZ2V0X3ZhcmlhYmxlKCJjb3VudGVyIikgICAgICAgICAgICAgICAgICAgICAgICAgICMgc2VhcmNoIGFsbCBtYWluIHRhc2tzIChmaXJzdCB2YWx1ZSBmb3VuZCkKYXdhaXQgY3R4LmdldF92YXJpYWJsZSgiY291bnRlciIsIHJvYm90X21vZGVsPSJDNTAwOTIwIikgICAjIGEgc3BlY2lmaWMgcm9ib3QncyB2YWx1ZQphd2FpdCBjdHguZ2V0X3ZhcmlhYmxlKCJSQlBfVEVTVCIsIHBsdWdpbl9pZD0iQS5wbHVnaW4iKSAgICMgdGhlIHZhbHVlIHRoYXQgcGx1Z2luIGxhc3Qgd3JvdGUKYGBgCgpDYXZlYXRzOgoKLSBJZiBubyBwcm9ncmFtIGlzIHJ1bm5pbmcsIGBzZXRfdmFyaWFibGVgIGlzICoqc2lsZW50bHkgaWdub3JlZCoqIGFuZAogIGBnZXRfdmFyaWFibGVgIHJldHVybnMgYE5vbmVgLiAoYFJ1bnRpbWVFcnJvcmAgaXMgcmFpc2VkIG9ubHkgZm9yIHJlYWwKICBlcnJvcnMsIGxpa2UgdGhlIGBSQlBfYCB2aW9sYXRpb24gb24gYSBuZXcgdmFyaWFibGUg4oCUIHRoZSBtZXNzYWdlIGlzIHRhZ2dlZAogIGBbcGx1Z2luOntpZH1dYCB3aXRoIHRoZSBvZmZlbmRpbmcgcGx1Z2luLikKLSBSYXJlbHksIGEgd3JpdGUgY2FuIGJlIGxvc3QgaWYgaXQgcmFjZXMgdGhlIHdvcmtlcidzIHZhcmlhYmxlIGZsdXNoCiAgKGxvY2stZnJlZSByZWFkLW1vZGlmeS13cml0ZSkuIEZvciBpbXBvcnRhbnQgdmFsdWVzLCByZS1jaGVjayBhbmQgcmV0cnkgb24KICB0aGUgbmV4dCBjeWNsZS4KCiMjIyMgUGVyLXBsdWdpbiB2YWx1ZSBzdG9yYWdlIChtZXRhKQoKQmVzaWRlcyB0aGUgc2hhcmVkIHZhbHVlLCBlYWNoIHZhcmlhYmxlIGVudHJ5IHJlY29yZHMgd2hpY2ggcGx1Z2luIGxhc3Qgd3JvdGUKd2hhdDoKCmBgYHB5dGhvbgojIHN0YXRlX2RpY3RbInZhcmlhYmxlcyJdIOKAlCBhZnRlciBBIHdyb3RlIDEgYW5kIEIgd3JvdGUgMgoiUkJQX1RFU1QiOiB7CiAgICAidmFsdWUiOiAyLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBzaGFyZWQgc2xvdCA9IGxhc3Qgd3JpdHRlbiB2YWx1ZQogICAgInR5cGUiOiAibG9jYWwiLAogICAgIm1ldGEiOiB7IndyaXRlcnMiOiB7IkEucGx1Z2luIjogMSwgIkIucGx1Z2luIjogMn19LCAgICMgcGVyLXBsdWdpbiByZWNvcmQKfQpgYGAKClNvIHRoZSBleGFjdCB2YWx1ZSBpcyByZWNvdmVyYWJsZSBldmVuIHdoZW4gbmFtZXMgY29sbGlkZToKCi0gUGx1Z2luIFNESzogYGN0eC5nZXRfdmFyaWFibGUoIlJCUF9URVNUIiwgcGx1Z2luX2lkPSJBLnBsdWdpbiIpYCDihpIgYDFgCi0gUHJvZ3JhbSBzdGVwIGV4cHJlc3Npb246IGBDT1VOVCA9IGdldF92YXIoIkEucGx1Z2luIiwgIlJCUF9URVNUIikgKyAxYCDihpIgYDJgCi0gQSBwbGFpbiBuYW1lIChgUkJQX1RFU1QgKz0gMWApIHVzZXMgdGhlIHNoYXJlZCBzbG90IChsYXN0IHdyaXR0ZW4gdmFsdWUpIOKGkiBgM2AKCiMjIyMgRXhlY3V0b3Igc3RhdGUKClN1YnNjcmliZXMgdG8gdGhlIGBtdXNjYXQvZXhlY3V0b3Ivc3RhdGVgIHB1Ymxpc2ggKDAuOCBzIGludGVydmFsKSBhbmQgZXhwb3NlcwpwZXItcm9ib3QtbW9kZWwgc3RhdGU6CgpgYGBweXRob24KY3R4LmV4ZWN1dG9yX3N0YXRlKCJDNTAwOTIwIikgICAjICJydW5uaW5nIiB8ICJwYXVzZWQiIHwgIndhaXRpbmciIHwgLi4uIHwgTm9uZQpjdHguZXhlY3V0b3Jfc3RhdGUoKSAgICAgICAgICAgICMgeyJDNTAwOTIwIjogInBhdXNlZCIsICJhbXIiOiAicnVubmluZyJ9CmN0eC5pc19wYXVzZWQoIkM1MDA5MjAiKSAgICAgICAgIyB3aGV0aGVyIHRoYXQgbW9kZWwgaXMgcGF1c2VkCmN0eC5pc19zdG9wcGVkKCJDNTAwOTIwIikgICAgICAgIyBzdG9wL2Vycm9yIHRyYW5zaXRpb24gb2YgYSBtb2RlbCBzZWVuIGFjdGl2ZSB0aGlzIHJ1bgpgYGAKCi0gU3RhdGVzOiBgaWRsZSB8IHJ1bm5pbmcgfCBwYXVzZWQgfCB3YWl0aW5nIHwgc3RvcHBlZCB8IHBvc3Rfc3RhcnQgfCBjb21wbGV0ZWQgfCBlcnJvcmAKLSBBIG1vZGVsIHdpdGggbm8gcnVubmluZyB0YXNrIGlzIGBOb25lYCAvIGFic2VudCBmcm9tIHRoZSBkaWN0LgotIFRoZSBwdWJsaXNoIGludGVydmFsIGlzIDAuOCBzLCBzbyBleHBlY3QgdXAgdG8gfjEgcyBvZiBsYXRlbmN5LgotIFdpdGggYElTX0RFVj10cnVlYCB0aGVyZSBpcyBubyBwdWJsaXNoIGF0IGFsbCDigJQgYWx3YXlzIGBOb25lYC4KClRvIGdldCBhIGNhbGxiYWNrIGF0IHRoZSBtb21lbnQgdGhlIHN0YXRlIGNoYW5nZXMsIHdpdGhvdXQgcG9sbGluZzoKCmBgYHB5dGhvbgpAY3R4Lm9uX2V4ZWN1dG9yX3N0YXRlX2NoYW5nZQphc3luYyBkZWYgb25fY2hhbmdlKHJvYm90X21vZGVsOiBzdHIsIHN0YXRlOiBzdHIpIC0+IE5vbmU6CiAgICBpZiBzdGF0ZSA9PSAicGF1c2VkIjoKICAgICAgICBwcmludChmIntyb2JvdF9tb2RlbH0gcGF1c2VkIikKYGBgCgotIE5vdCBjYWxsZWQgZm9yIHJlcGVhdGVkIHB1Ymxpc2hlcyBvZiB0aGUgc2FtZSBzdGF0ZSDigJQgZmlyZXMgZXhhY3RseSBvbmNlCiAgcGVyIHBlci1tb2RlbCBzdGF0ZSBjaGFuZ2UuCi0gQW4gZXhjZXB0aW9uIGluIHRoZSBoYW5kbGVyIGlzIG9ubHkgbG9nZ2VkOyBzdGF0ZSB0cmFja2luZyBrZWVwcyBydW5uaW5nLgoKIyMjIyBSZXNwb25kaW5nIHRvIHBhdXNlIC8gc3RvcAoKYGBgcHl0aG9uCkBjdHgub25fZXhlY3V0ZQphc3luYyBkZWYgaGFuZGxlKGFyZ3M6IGRpY3QpIC0+IE5vbmU6CiAgICBmb3IgaSBpbiByYW5nZSgxMDApOgogICAgICAgICMgc3RvcCDihpIgQ2FuY2VsbGVkRXJyb3IgKHByb3BhZ2F0ZWQgdG8gdGhlIGV4ZWN1dG9yIGFzIGEgc3RvcCksCiAgICAgICAgIyBwYXVzZSDihpIgd2FpdHMgaGVyZSB1bnRpbCByZXN1bWVkLgogICAgICAgICMgSW5zaWRlIG9uX2V4ZWN1dGUgdGhpcyBhdXRvbWF0aWNhbGx5IHdhdGNoZXMgb25seSB0aGUgcm9ib3QgbW9kZWwKICAgICAgICAjIGV4ZWN1dGluZyB0aGlzIFN0ZXAuCiAgICAgICAgYXdhaXQgY3R4LmNoZWNrX3N0b3AoKQoKICAgICAgICAuLi4gICMgYWN0dWFsIHdvcmsKICAgICAgICBhd2FpdCBhc3luY2lvLnNsZWVwKDAuNSkKCiAgICBhd2FpdCBjdHguZG9uZSgpCmBgYAoKU2NvcGUgcHJpb3JpdHkgZm9yIGBjaGVja19zdG9wYCAvIGBpc19wYXVzZWRgIC8gYGlzX3N0b3BwZWRgOgoKMS4gYHJvYm90X21vZGVsYCBnaXZlbiDigJQgdGhhdCBtb2RlbCBvbmx5CjIuIE9taXR0ZWQgaW5zaWRlIGBvbl9leGVjdXRlYCDigJQgKipvbmx5IHRoZSBtb2RlbCBleGVjdXRpbmcgdGhpcyBTdGVwKioKICAgKHBhc3NlZCBpbiBieSB0aGUgZXhlY3V0b3IpCjMuIE9taXR0ZWQgZWxzZXdoZXJlIChyZXNpZGVudCB0YXNrLCDigKYpIOKAlCBhbGwgbW9kZWxzCgpBIGhhbmRsZXIgZG9pbmcgbG9uZy1ydW5uaW5nIHdvcmsgbXVzdCBjYWxsIGBjaGVja19zdG9wKClgIGV2ZXJ5IGxvb3AKaXRlcmF0aW9uIHNvIGl0IHJlYWN0cyB0byBwYXVzZS9zdG9wIGltbWVkaWF0ZWx5LiBXaXRob3V0IGl0LCB0aGUgcGx1Z2luIGtlZXBzCnJ1bm5pbmcgZXZlbiBhZnRlciB0aGUgb3BlcmF0b3IgcHJlc3NlcyBTdG9wLgoKVmFyaWFibGVzIHlvdXIgcGx1Z2luIHdhbnRzIHRoZSBQcm9ncmFtIHBhZ2UgdmFyaWFibGUgcGlja2VyIHRvIG9mZmVyIG11c3QgYmUKcHJlLWRlY2xhcmVkIGluIGBtYW5pZmVzdC5qc29uYCB1bmRlciBgInZhcmlhYmxlcyJgIChzZWUgdGhlIG1hbmlmZXN0IHNlY3Rpb24KYmVsb3cpLgoKIyMjIEMrKwoKQysrIHBsdWdpbnMgdXNlIGBjcHAvYCBhbmQgYXJlIGJ1aWx0IHdpdGggQ01ha2UgaW5zaWRlIERvY2tlciBhZ2FpbnN0IHRoZQpSYWluYm93IFJvYm90aWNzIEMrKyBTREsgKHNlZSBfQysrIFNES18gYmVsb3cpLgoKYGBgY3BwCiNpbmNsdWRlIDxjaHJvbm8+CiNpbmNsdWRlIDxjc3RkbGliPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxzdHJpbmc+CiNpbmNsdWRlIDx0aHJlYWQ+CgppbnQgbWFpbigpIHsKICBjb25zdCBjaGFyKiBwbHVnaW5faWQgPSBzdGQ6OmdldGVudigiUkJfUExVR0lOX0lEIik7CiAgc3RkOjpjb3V0IDw8ICJbX19QTFVHSU5fTkFNRV9fXSBiYWNrZW5kIHJlYWR5IgogICAgICAgICAgICA8PCAocGx1Z2luX2lkID8gc3RkOjpzdHJpbmcoIiAoaWQ9IikgKyBwbHVnaW5faWQgKyAiKSIgOiAiIikKICAgICAgICAgICAgPDwgc3RkOjplbmRsOwoKICB3aGlsZSAodHJ1ZSkgewogICAgc3RkOjp0aGlzX3RocmVhZDo6c2xlZXBfZm9yKHN0ZDo6Y2hyb25vOjpzZWNvbmRzKDEpKTsKICB9CiAgcmV0dXJuIDA7Cn0KYGBgCgojIyMjIEMrKyBTREsgKGByYWluYm93LXJiLXNkay1kZXZgKQoKQm90aCBDKysgcnVudGltZXMgKGBjcHBgLCBgcm9zMmAgKyBgcmNsY3BwYCkgbGluayB0aGUgUmFpbmJvdyBSb2JvdGljcyBDKysgU0RLCmZyb20gdGhlIGFwdCBwYWNrYWdlIGByYWluYm93LXJiLXNkay1kZXZgLiBUaGUgYG11c2NhdC1wa2AgZGV2IGNvbnRhaW5lcnMgYWxyZWFkeQpoYXZlIGl0LCBzbyBgbXVzY2F0LXBrIGRldmAgLyBgYnVpbGRgIG5lZWQgbm90aGluZyBleHRyYS4gVG8gYnVpbGQgb3V0c2lkZSB0aGUKY29udGFpbmVyICh5b3VyIG93biBVYnVudHUgMjQuMDQgbWFjaGluZSwgb3IgdGhlIHJvYm90IFBDKToKCmBgYGJhc2gKY3VybCAtZnNTTCBodHRwczovL3JhaW5ib3dyb2JvdGljcy5naXRodWIuaW8vcmItc2RrL3JiLXNkay1hcHQtcmVwby5ncGcua2V5IHwgc3VkbyBncGcgLS1kZWFybW9yIC1vIC91c3Ivc2hhcmUva2V5cmluZ3MvcmItc2RrLWFwdC5ncGcKZWNobyAnZGViIFtzaWduZWQtYnk9L3Vzci9zaGFyZS9rZXlyaW5ncy9yYi1zZGstYXB0LmdwZ10gaHR0cHM6Ly9yYWluYm93cm9ib3RpY3MuZ2l0aHViLmlvL3JiLXNkayBzdGFibGUgbWFpbicgfCBzdWRvIHRlZSAvZXRjL2FwdC9zb3VyY2VzLmxpc3QuZC9yYi1zZGsubGlzdApzdWRvIGFwdCB1cGRhdGUgJiYgc3VkbyBhcHQgaW5zdGFsbCByYWluYm93LXJiLXNkay1kZXYKYGBgCgotIENNYWtlOiBgZmluZF9wYWNrYWdlKHJiX3NkayBSRVFVSVJFRClgICsgYHRhcmdldF9saW5rX2xpYnJhcmllcyg8dGFyZ2V0PiByYl9zZGs6OnJiX3NkaylgIChDKysyMCkuIHBrZy1jb25maWc6IGByYl9zZGtgLgotIEhlYWRlcnM6IGA8cmFpbmJvdy9yYl9zZGsvbWFuaXB1bGF0ZS9yYl9tYW5pcHVsYXRlX3Nkay5ocHA+YCAoYFJCTWFuaXB1bGF0ZVNES2ApLAogIGA8cmFpbmJvdy9yYl9zZGsvcHJvZ3JhbS9wbHVnaW5fcHJvZ3JhbV9jb250ZXh0LmhwcD5gIChgcmJfcGx1Z2luOjpQbHVnaW5Qcm9ncmFtQ29udGV4dGAsIGZvciBgcHJvZ3JhbS5wYW5lbGAgY29tbWFuZHMg4oCUIHRoZSBoZWFkZXIncyB0b3AgY29tbWVudCBoYXMgYSBmdWxsIGBtYWluKClgIGV4YW1wbGUpLgotIFRoZSBiaW5hcnkgaXMgbGlua2VkICoqZHluYW1pY2FsbHkqKjsgYG11c2NhdC1wayBidWlsZGAgY29waWVzIHRoZSBtYXRjaGluZyBgbGlicmJfc2RrLnNvYCBpbnRvIGBkaXN0LzxhcmNoPi9saWIvYCAodGhlIHJvYm90IGhhcyBubyBTREsgaW5zdGFsbGVkKSwgc28gZWFjaCBwbHVnaW4ga2VlcHMgdGhlIFNESyB2ZXJzaW9uIGl0IHdhcyBidWlsdCB3aXRoLiBUaGUgdmVyc2lvbiBpcyB0aGUgb25lIHBpbm5lZCBpbiBgQ01ha2VMaXN0cy50eHRgIChgZmluZF9wYWNrYWdlKHJiX3NkayA8dmVyc2lvbj4gRVhBQ1QgUkVRVUlSRUQpYCk7IGNoYW5nZSBpdCB3aXRoIGBtdXNjYXQtcGsgc2RrIHVwZGF0ZSA8dmVyc2lvbj5gLgotIFVJIOKGlCBiYWNrZW5kIG1lc3NhZ2luZyB3b3JrcyBmcm9tIEMrKyB0b286IGByYl9wbHVnaW46OlJCUGx1Z2luQ2FsbGAgaW4gYDxyYWluYm93L3JiX3Nkay9wbHVnaW4vcmJfcGx1Z2luLmhwcD5gIChzZWUgdGhlIHNjYWZmb2xkZWQgYGNwcC9tYWluLmNwcGApLgoKIyMjIFJPUzIgKHJjbHB5KQoKUk9TMiBQeXRob24gcGx1Z2lucyB1c2UgYHJvczJfd3MvYCB3aXRoIGBydW50aW1lLnJvc0NsaWVudDogInJjbHB5ImAuIHJlbGF0aXZlIHRvcGljIG5hbWVzIGFyZSBwbGFjZWQgdW5kZXIgdGhlIHBsdWdpbidzIFJPUyBuYW1lc3BhY2Ug4oCUIHRoZSBwbHVnaW4gaWQKd2l0aCAiLiIg4oaSICIvIiBhbmQgIi0iIOKGkiAiXyIgKGBjb20uZXhhbXBsZS5teS1wbHVnaW5gIOKGkiBgL2NvbS9leGFtcGxlL215X3BsdWdpbmApLCBpbiBkZXYKYW5kIG9uIHRoZSByb2JvdC4gVXNlIGFuIGFic29sdXRlIG5hbWUgKGAvY21kX3ZlbGApIGZvciB0b3BpY3Mgc2hhcmVkIHdpdGggb3RoZXIgbm9kZXMuCmBSQlBsdWdpbkNhbGxgIHdvcmtzIGluIHRoZSBub2RlIG1vZHVsZSB0b28gKFVJIG1lc3NhZ2luZyBhbmQgYHBsdWdpbi5yb3V0ZXJgKS4KCmBgYHB5dGhvbgojIHJvczJfd3Mvc3JjL19fUExVR0lOX1NMVUdfXy9fX1BMVUdJTl9TTFVHX18vbm9kZS5weQppbXBvcnQgcmNscHkKZnJvbSByY2xweS5ub2RlIGltcG9ydCBOb2RlCmZyb20gcmFpbmJvdy5yYl9zZGsgaW1wb3J0IFJCTWFuaXB1bGF0ZVNESwoKc2RrID0gUkJNYW5pcHVsYXRlU0RLKCkKCgpjbGFzcyBfX1BMVUdJTl9DTEFTU19fTm9kZShOb2RlKToKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICBzdXBlcigpLl9faW5pdF9fKCJfX1BMVUdJTl9TTFVHX19fbm9kZSIpCiAgICAgICAgc2VsZi5nZXRfbG9nZ2VyKCkuaW5mbygiX19QTFVHSU5fTkFNRV9fIG5vZGUgc3RhcnRlZCIpCiAgICAgICAgIyB1c2Ugc2RrIGFsb25nc2lkZSBST1MyIHB1Ymxpc2hlcnMvc3Vic2NyaWJlcnMvc2VydmljZXMgYXMgbmVlZGVkCmBgYAoKCiMjIyMgVGFsa2luZyB0byBhbiBleHRlcm5hbCBQQyBvdmVyIFJPUyAyCgpST1MgMiBkaXNjb3Zlcnkgc3RheXMgb24gdGhlIHJvYm90IChgUk9TX0FVVE9NQVRJQ19ESVNDT1ZFUllfUkFOR0U9TE9DQUxIT1NUYDsgYG11c2NhdC1wayBkZXZgCnJ1bnMgdGhlIHNhbWUpLCBzbyByb2JvdHMgb24gb25lIExBTiBkb24ndCBtaXggdG9waWNzLiBBbGxvdyBzcGVjaWZpYyBQQ3MgZnJvbSB0aGUgcGx1Z2luIFVJIOKAlApNdXNjYXQga2VlcHMgdGhlIGxpc3QgcGVyIHBsdWdpbiwgc3RhcnRzIHlvdXIgYmFja2VuZCB3aXRoIGBST1NfU1RBVElDX1BFRVJTYCBzZXQgdG8gaXQsIGFuZApyZXN0YXJ0cyB0aGUgcGx1Z2luIHdoZW4gaXQgY2hhbmdlcy4gWW91ciBST1MgY29kZSBuZWVkcyBubyBjaGFuZ2VzOyB0aGUgUEMgbmVlZHMgbm8gZXh0cmEgc2V0dGluZ3MuCgpgYGB0c3gKY29uc3QgcmIgPSB1c2VSYigpOwpjb25zdCBwZWVycyA9IGF3YWl0IHJiLnJvc1BlZXJzLmdldCgpOyAgICAgICAgICAgICAgIC8vIFsiMTkyLjE2OC4wLjUwIl0KYXdhaXQgcmIucm9zUGVlcnMuc2V0KFsiMTkyLjE2OC4wLjUwIiwgIjE5Mi4xNjguMC41MSJdKTsgLy8gc2F2ZXMgKyByZXN0YXJ0cyB0aGUgcGx1Z2luOyByZWplY3RzIG9uIGEgYmFkIElQCmBgYAoKLSBQZXIgcGx1Z2luOiBwbHVnaW4gQiBrZWVwcyBpdHMgYWxsb3dlZCBQQ3Mgd2hlbiBwbHVnaW4gQSAoYWxsb3dpbmcgdGhlIHNhbWUgUEMpIGlzIHN0b3BwZWQgb3IgcmVtb3ZlZC4KLSBJdCBvcGVucyBjb21tdW5pY2F0aW9uOyBpdCBpcyBub3QgYWNjZXNzIGNvbnRyb2wg4oCUIGEgUEMgdGhhdCBrbm93cyB0aGUgcm9ib3QncyBJUCBjYW4gc3RpbGwKICBhZGQgdGhlIHJvYm90IHRvIGl0cyBvd24gYFJPU19TVEFUSUNfUEVFUlNgLgotIEluIGBtdXNjYXQtcGsgZGV2YCB0aGUgbGlzdCBpcyBrZXB0IGluIGAubXVzY2F0LWRldi9yb3MtcGVlcnMuanNvbmAgKFJPUyAyIGJhY2tlbmRzKS4KCiMjIyBST1MyIChyY2xjcHApCgpST1MyIEMrKyBwbHVnaW5zIHVzZSBgcm9zMl93cy9gIHdpdGggYHJ1bnRpbWUucm9zQ2xpZW50OiAicmNsY3BwImAuIFRoZSBub2RlIGxpbmtzCnRoZSBSYWluYm93IEMrKyBTREsgdGhlIHNhbWUgd2F5IGFzIHRoZSBgY3BwYCBydW50aW1lIChzZWUgX0MrKyBTREtfIGFib3ZlKS4KCmBgYGNwcAojaW5jbHVkZSAicmNsY3BwL3JjbGNwcC5ocHAiCgpjbGFzcyBfX1BMVUdJTl9DTEFTU19fTm9kZSA6IHB1YmxpYyByY2xjcHA6Ok5vZGUgewpwdWJsaWM6CiAgX19QTFVHSU5fQ0xBU1NfX05vZGUoKSA6IE5vZGUoIl9fUExVR0lOX1NMVUdfX19ub2RlIikgewogICAgUkNMQ1BQX0lORk8odGhpcy0+Z2V0X2xvZ2dlcigpLCAiX19QTFVHSU5fTkFNRV9fIG5vZGUgc3RhcnRlZCIpOwogIH0KfTsKYGBgCgotLS0KCiMjIFZpZGVvIHN0cmVhbWluZyAoTWVkaWFNVFgpCgpNdXNjYXQgcnVucyBhIE1lZGlhTVRYIG1lZGlhIHNlcnZlci4gVGhlIGJhY2tlbmQgcHVibGlzaGVzIGEgc3RyZWFtIG92ZXIgUlRTUCBhbmQKdGhlIFVJIHBsYXlzIGl0IG92ZXIgV2ViUlRDLiBgbXVzY2F0LXBrIGRldmAgcnVucyB0aGUgc2FtZSBzZXJ2ZXIgKG9yIHVzZXMgYSBsb2NhbApNdXNjYXQncyksIHNvIHRoZSBhZGRyZXNzZXMgYXJlIGlkZW50aWNhbCBpbiBkZXYgYW5kIG9uIHRoZSByb2JvdC4KCnwgfCBBZGRyZXNzIHwKfCAtLS0gfCAtLS0gfAp8IFB1Ymxpc2ggKGJhY2tlbmQpIHwgYHJ0c3A6Ly8xMjcuMC4wLjE6ODU1NC88cGx1Z2luX2lkPi88bmFtZT5gIHwKfCBQbGF5IChVSSkgfCBgaHR0cDovLzxob3N0Pjo4ODg5LzxwbHVnaW5faWQ+LzxuYW1lPi9gIHwKCi0gUHJlZml4IHRoZSBwYXRoIHdpdGggeW91ciBwbHVnaW4gaWQg4oCUIHBhdGhzIGFyZSBzaGFyZWQgd2l0aCByb2JvdCBjYW1lcmFzIGFuZCBvdGhlciBwbHVnaW5zLgotIFRoZSByb2JvdCBydW50aW1lIGhhcyBubyBmZm1wZWcsIEdTdHJlYW1lciBvciBPcGVuQ1Y7IGJyaW5nIHlvdXIgb3duIGVuY29kZXIgKGJlbG93KS4KCioqQmFja2VuZCAoUHl0aG9uKSoqIOKAlCB1c2UgUHlBVjogYWRkIGBhdmAgYW5kIGBudW1weWAgdG8gYHJlcXVpcmVtZW50cy50eHRgLiBJdHMgd2hlZWxzCmluY2x1ZGUgRkZtcGVnLCBzbyB0aGV5IHNoaXAgaW4gdGhlIFpJUCBsaWtlIGFueSBvdGhlciBkZXBlbmRlbmN5LgoKYGBgcHl0aG9uCmltcG9ydCBmcmFjdGlvbnMsIHRpbWUKaW1wb3J0IGF2LCBudW1weSBhcyBucAoKb3V0ID0gYXYub3BlbigicnRzcDovLzEyNy4wLjAuMTo4NTU0L19fUExVR0lOX0lEX18vY2FtIiwgbW9kZT0idyIsIGZvcm1hdD0icnRzcCIsCiAgICAgICAgICAgICAgb3B0aW9ucz17InJ0c3BfdHJhbnNwb3J0IjogInRjcCJ9KQpzdHJlYW0gPSBvdXQuYWRkX3N0cmVhbSgibGlieDI2NCIsIHJhdGU9MjUsIG9wdGlvbnM9eyJwcmVzZXQiOiAidWx0cmFmYXN0IiwgInR1bmUiOiAiemVyb2xhdGVuY3kifSkKc3RyZWFtLndpZHRoLCBzdHJlYW0uaGVpZ2h0LCBzdHJlYW0ucGl4X2ZtdCA9IDY0MCwgMzYwLCAieXV2NDIwcCIKCmkgPSAwCndoaWxlIFRydWU6CiAgICBpbWcgPSBucC56ZXJvcygoMzYwLCA2NDAsIDMpLCBkdHlwZT1ucC51aW50OCkgICAgICAgICAgIyB5b3VyIFJHQiBmcmFtZSBoZXJlCiAgICBmcmFtZSA9IGF2LlZpZGVvRnJhbWUuZnJvbV9uZGFycmF5KGltZywgZm9ybWF0PSJyZ2IyNCIpCiAgICBmcmFtZS5wdHMsIGZyYW1lLnRpbWVfYmFzZSA9IGksIGZyYWN0aW9ucy5GcmFjdGlvbigxLCAyNSkKICAgIGZvciBwYWNrZXQgaW4gc3RyZWFtLmVuY29kZShmcmFtZSk6CiAgICAgICAgb3V0Lm11eChwYWNrZXQpCiAgICBpICs9IDEKICAgIHRpbWUuc2xlZXAoMSAvIDI1KQpgYGAKClJ1biB0aGUgZW5jb2RlciBsb29wIGluIGEgdGhyZWFkIChvciBgYXN5bmNpby50b190aHJlYWRgKSBzbyBpdCBkb2Vzbid0IGJsb2NrIHRoZQpgUkJQbHVnaW5DYWxsYCBoYW5kbGVycy4KCioqVUkqKiDigJQgZW1iZWQgTWVkaWFNVFgncyBXZWJSVEMgcGxheWVyLiBgbG9jYXRpb24uaG9zdG5hbWVgIGlzIGBsb2NhbGhvc3RgIGluIHRoZQpwcmV2aWV3IGFuZCB0aGUgcm9ib3QncyBhZGRyZXNzIG9uIHRoZSByb2JvdDoKCmBgYHRzeApjb25zdCBTVFJFQU0gPSAiX19QTFVHSU5fSURfXy9jYW0iOyAvLyB0aGUgcGF0aCB0aGUgYmFja2VuZCBwdWJsaXNoZXMKCmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIENhbWVyYSgpIHsKICByZXR1cm4gKAogICAgPGlmcmFtZQogICAgICBzcmM9e2Ake2xvY2F0aW9uLnByb3RvY29sfS8vJHtsb2NhdGlvbi5ob3N0bmFtZX06ODg4OS8ke1NUUkVBTX0vYH0KICAgICAgYWxsb3c9ImF1dG9wbGF5IgogICAgICBjbGFzc05hbWU9ImFzcGVjdC12aWRlbyB3LWZ1bGwgYm9yZGVyLTAiCiAgICAvPgogICk7Cn0KYGBgCgotLS0KCiMjIG1hbmlmZXN0Lmpzb24KCmBgYGpzb25jCnsKICAvLyB1bmlxdWUgcGx1Z2luIElEIOKAlCByZXZlcnNlLWRvbWFpbiBmb3JtYXQgcmVjb21tZW5kZWQKICAiaWQiOiAiY29tLmV4YW1wbGUubXktcGx1Z2luIiwKICAibmFtZSI6ICJNeSBQbHVnaW4iLAogICJ2ZXJzaW9uIjogIjEuMC4wIiwKCiAgLy8gbWluaW11bSBNdXNjYXQgdmVyc2lvbiByZXF1aXJlZCB0byBsb2FkIHRoaXMgcGx1Z2luCiAgIm1pbk11c2NhdFZlcnNpb24iOiAiMS4wLjAiLAoKICAvLyBwbHVnaW4gYXV0aG9yIChlbXB0eSBzdHJpbmcgaXMgZmluZSkKICAiYXV0aG9yIjogIllvdXIgTmFtZSIsCgogIC8vIGRpc3BsYXllZCBpbiB0aGUgTXVzY2F0IHBsdWdpbiBzdG9yZSAvIGluZm8gcGFuZWwKICAvLyBzdHJpbmcgb3IgeyBlbiAocmVxdWlyZWQpLCBrbywgamEsIHpoLCB2aSwgdGgsIGVzIH0KICAiZGVzY3JpcHRpb24iOiB7ICJlbiI6ICJQbHVnaW4gZGVzY3JpcHRpb24iLCAia28iOiAi7ZSM65+s6re47J24IOyEpOuqhSIgfSwKCiAgLy8gU1ZHIHN0cmluZyAoc2luZ2xlIGZpbGUpIG9yIFBORy9KUEcgc2l6ZSBtYXAgKGFsbCB0aHJlZSBzaXplcyByZXF1aXJlZCkKICAiaWNvbnMiOiAiYXNzZXRzL2ljb24uc3ZnIiwKICAvLyAiaWNvbnMiOiB7ICIxNiI6ICJhc3NldHMvaWNvbi0xNi5wbmciLCAiNDgiOiAiYXNzZXRzL2ljb24tNDgucG5nIiwgIjEyOCI6ICJhc3NldHMvaWNvbi0xMjgucG5nIiB9LAoKICAvLyB0YXJnZXRNb2RlbHMgYW5kL29yIHRhcmdldENhdGVnb3J5cyDigJQgYXQgbGVhc3Qgb25lIGlzIHJlcXVpcmVkCiAgLy8gImFsbCIgPSBldmVyeSB0YXJnZXQsIG9yIGxpc3Qgc3BlY2lmaWMgdmFsdWVzCiAgInRhcmdldE1vZGVscyI6ICJhbGwiLAogIC8vICJ0YXJnZXRNb2RlbHMiOiBbIkM1MDA5MjAiLCAiQzUwMDkzMCJdLAogICJ0YXJnZXRDYXRlZ29yeXMiOiAiYWxsIiwKICAvLyAidGFyZ2V0Q2F0ZWdvcnlzIjogWyJtYW5pcHVsYXRlIiwgImFtciIsICJyYnkxIiwgInZpc2lvbiJdLAoKICAiY29udHJpYnV0ZXMiOiBbCiAgICAvLyBwcm9ncmFtLnBhbmVsIOKAlCBkZWZpbmVzIGEgY3VzdG9tIGNvbW1hbmQgZm9yIHRoZSBQcm9ncmFtIHBhZ2Ugc2VxdWVuY2UKICAgIC8vICAgYnVpbGRlcjsgcnVucyB2aWEgUGx1Z2luUHJvZ3JhbUNvbnRleHQgd2hlbiB0aGUgcHJvZ3JhbSByZWFjaGVzIGl0CiAgICB7CiAgICAgICJwb2ludCI6ICJwcm9ncmFtLnBhbmVsIiwKICAgICAgImljb24iOiAiYXNzZXRzL2ljb24uc3ZnIiwKICAgICAgImxhYmVsIjogeyAia28iOiAi64K0IO2UjOufrOq3uOyduCIsICJlbiI6ICJNeSBQbHVnaW4iIH0sCiAgICAgICJ1aSI6ICJwcm9ncmFtIiwgICAgICAgICAgIC8vIG11c3QgYmUgdW5pcXVlIGFjcm9zcyBhbGwgY29udHJpYnV0aW9ucwogICAgICAiY29tbWFuZEluZm8iOiB7CiAgICAgICAgIm5hbWUiOiAiTXkgUGx1Z2luIiwKICAgICAgICAiaWNvbiI6ICJhc3NldHMvaWNvbi5zdmciLAogICAgICAgICJmdW5jTmFtZSI6ICJyYl9wcm9ncmFtX3Nkay5wbHVnaW5fZXhlY3V0ZSIsCiAgICAgICAgImFyZ3MiOiB7fQogICAgICB9CiAgICB9LAogICAgLy8gdG9vbGJhciDigJQgYWRkcyBhIGJ1dHRvbiB0byB0aGUgdG9wIHRvb2xiYXIgKHJlcXVpcmVkKQogICAgewogICAgICAicG9pbnQiOiAidG9vbGJhciIsCiAgICAgICJpY29uIjogImFzc2V0cy9pY29uLnN2ZyIsCiAgICAgICJsYWJlbCI6IHsgImtvIjogIuuCtCDtlIzrn6zqt7jsnbgiLCAiZW4iOiAiTXkgUGx1Z2luIiB9LAogICAgICAidWkiOiAiY29udGVudCIsICAgICAgICAgICAvLyBtdXN0IGJlIHVuaXF1ZSBhY3Jvc3MgYWxsIGNvbnRyaWJ1dGlvbnMKICAgICAgIm9wZW5zIjogInBvcG92ZXIiICAgICAgICAgLy8gcG9wb3ZlciB8IHBhbmVsIHwgcGFnZQogICAgfSwKICAgIC8vIG1vdmUucGFuZWwg4oCUIGFkZHMgYSBwYW5lbCB0byB0aGUgTW92ZSBzY3JlZW4KICAgIHsKICAgICAgInBvaW50IjogIm1vdmUucGFuZWwiLAogICAgICAiaWNvbiI6ICJhc3NldHMvaWNvbi5zdmciLAogICAgICAibGFiZWwiOiB7ICJrbyI6ICLrgrQg7ZSM65+s6re47J24IiwgImVuIjogIk15IFBsdWdpbiIgfSwKICAgICAgInVpIjogIm1vdmUiICAgICAgICAgICAgICAgLy8gbXVzdCBiZSB1bmlxdWUgYWNyb3NzIGFsbCBjb250cmlidXRpb25zCiAgICB9CiAgXSwKCiAgLy8gb3B0aW9uYWw6IHZhcmlhYmxlcyB0aGlzIHBsdWdpbiBleHBvc2VzIHRvIHB5Zm0gcHJvZ3JhbXMg4oCUIHRoZSBQcm9ncmFtCiAgLy8gcGFnZSB2YXJpYWJsZSBwaWNrZXIgbGlzdHMgT05MWSBkZWNsYXJlZCB2YXJpYWJsZXMuIG5hbWUgbXVzdCBzdGFydCB3aXRoCiAgLy8gUkJQXzsgZGVzY3JpcHRpb24gaXMgb3B0aW9uYWwgYnV0IHdpdGhvdXQgaXQgdGhlIFVJIGNhbid0IGV4cGxhaW4gdGhlCiAgLy8gdmFyaWFibGUsIHNvIHdyaXRlIG9uZS4KICAidmFyaWFibGVzIjogWwogICAgeyAibmFtZSI6ICJSQlBfZ3JpcF9mb3JjZSIsICJ0eXBlIjogIm51bWJlciIsICJpbml0IjogMC41LCAiZGVzY3JpcHRpb24iOiB7ICJrbyI6ICLqt7jrpqztjbwg7Z6YIiwgImVuIjogIkdyaXBwZXIgZm9yY2UiIH0gfSwKICAgIHsgIm5hbWUiOiAiUkJQX3RhcmdldF9wb3NlIiwgInR5cGUiOiAiYXJyYXkiLCAiaW5pdCI6IFswLCAwLCAwXSB9CiAgXSwKCiAgLy8gcnVudGltZSDigJQgb25lIG9mOgogIC8vICAgeyAidHlwZSI6ICJub25lIiB9CiAgLy8gICB7ICJ0eXBlIjogInB5dGhvbiIsICJlbnRyeSI6ICJtYWluLnB5IiB9CiAgLy8gICB7ICJ0eXBlIjogImNwcCIsICJlbnRyeSI6ICI8ZXhlY3V0YWJsZSBuYW1lPiIgfQogIC8vICAgeyAidHlwZSI6ICJyb3MyIiwgInJvc0NsaWVudCI6ICJyY2xweSIgfCAicmNsY3BwIiwgInBhY2thZ2UiOiAiLi4uIiwgImxhdW5jaCI6ICIuLi5fbm9kZSIgfQogICJydW50aW1lIjogeyAidHlwZSI6ICJweXRob24iLCAiZW50cnkiOiAibWFpbi5weSIgfSwKCiAgLy8gb3B0aW9uYWw6IFRDUCBwb3J0cyBvcGVuZWQgYnkgdGhpcyBwbHVnaW4gYmFja2VuZAogIC8vIG9ubHkgbnVtYmVyW10gaXMgYWxsb3dlZDsgcmFuZ2VzL29iamVjdHMgYXJlIG5vdCBhY2NlcHRlZAogIC8vIGV4dGVybmFsIHBsdWdpbiBwb3J0cyBtdXN0IGJlIHdpdGhpbiAyODYwMC0yODk5OQogICJwb3J0cyI6IFsyODYwMF0KfQpgYGAKCioqQmFja2VuZCB0eXBlczoqKgoKfCB0eXBlIHwgc291cmNlIGRpciB8IGJ1aWxkIC8gcnVuIHwgZW50cnkgfAp8LS0tfC0tLXwtLS18LS0tfAp8IGBweXRob25gIHwgYHB5L2AgfCBwaXAgKyBydW4gaW4gRG9ja2VyIHwgYG1haW4ucHlgIHwKfCBgY3BwYCB8IGBjcHAvYCB8IENNYWtlIGluIERvY2tlciB8IGJ1aWx0IGV4ZWN1dGFibGUgbmFtZSB8CnwgYHJvczJgIChyY2xweSkgfCBgcm9zMl93cy9gIHwgY29sY29uIChhbWVudF9weXRob24pIGluIERvY2tlciB8IOKAlCB8CnwgYHJvczJgIChyY2xjcHApIHwgYHJvczJfd3MvYCB8IGNvbGNvbiAoYW1lbnRfY21ha2UpIGluIERvY2tlciB8IOKAlCB8Cgo+IEV2ZXJ5IGJhY2sgZW5kIHJ1bnMgaW4gYSBEb2NrZXIgY29udGFpbmVyIG1hdGNoaW5nIHRoZSByb2JvdCAoVWJ1bnR1IDI0LjA0ICsgUHl0aG9uIDMuMTIpLCBzbyBkZXYgYmVoYXZlcyBsaWtlIHByb2R1Y3Rpb24gYW5kIGNvbXBpbGVkIGJpbmFyaWVzIGFyZSBBQkktY29tcGF0aWJsZS4gKipEb2NrZXIgaXMgcmVxdWlyZWQqKiBmb3IgYWxsIGJhY2tlbmQgdHlwZXMgKG9ubHkgYSBmcm9udGVuZC1vbmx5IGBub25lYCBwbHVnaW4gc2tpcHMgaXQpLiBObyBsb2NhbCBQeXRob24vdG9vbGNoYWluIHNldHVwIGlzIG5lZWRlZC4KCioqQ29udHJpYnV0aW9uIHBvaW50czoqKgoKfCBwb2ludCB8IFdoZXJlIGl0IGFwcGVhcnMgfCBCYWNrZW5kIHwgYGNvbW1hbmRJbmZvYCB8CnwtLS18LS0tfC0tLXw6LS0tOnwKfCBgdG9vbGJhcmAgfCBUb3AgdG9vbGJhciBidXR0b24gKG11c3QgaGF2ZSBhdCBsZWFzdCBvbmUpIHwgU0RLIC8gYHJiLmFjdGlvbmAgfCDigJQgfAp8IGBsbmJgIHwgTGVmdCBuYXZpZ2F0aW9uIGVudHJ5IHwgU0RLIC8gYHJiLmFjdGlvbmAgfCDigJQgfAp8IGBtb3ZlLnBhbmVsYCB8IE1vdmUgc2NyZWVuIHBhbmVsIHwgU0RLIC8gYHJiLmFjdGlvbmAgfCDigJQgfAp8IGBwcm9ncmFtLnBhbmVsYCB8IEN1c3RvbSBjb21tYW5kIGluIHRoZSBQcm9ncmFtIHBhZ2Ugc2VxdWVuY2UgYnVpbGRlciB8IGBQbHVnaW5Qcm9ncmFtQ29udGV4dGAgfCDinJMgfAoKKipgY29tbWFuZEluZm9gIGZpZWxkcyoqIChmb3IgYHByb2dyYW0ucGFuZWxgKToKCnwgZmllbGQgfCB0eXBlIHwgZGVzY3JpcHRpb24gfAp8LS0tfC0tLXwtLS18CnwgYG5hbWVgIHwgYHN0cmluZ2AgfCBEaXNwbGF5IG5hbWUgb2YgdGhlIGNvbW1hbmQgaW4gdGhlIHByb2dyYW0gdHJlZSB8CnwgYGljb25gIHwgYHN0cmluZ2AgfCBJY29uIHBhdGggfAp8IGBpY29uQ2xhc3NOYW1lYCB8IGBzdHJpbmc/YCB8IE9wdGlvbmFsIENTUyBjbGFzcyBmb3IgdGhlIGljb24gfAp8IGBmdW5jTmFtZWAgfCBgc3RyaW5nP2AgfCBCYWNrZW5kIGZ1bmN0aW9uIG5hbWUgdG8gY2FsbCB8CnwgYGFyZ3NgIHwgYFJlY29yZDxzdHJpbmcsIGFueT4/YCB8IERlZmF1bHQgYXJndW1lbnRzIHwKfCBgZGlzYWJsZWRgIHwgYGJvb2xlYW4/YCB8IFdoZXRoZXIgdGhlIG5vZGUgaXMgZGlzYWJsZWQgfAp8IGBhbGxvd0NoaWxkcmVuYCB8IGBzdHJpbmdbXT9gIHwgQWxsb3dlZCBjaGlsZCBjb21tYW5kcyB8CnwgYGFsbG93UGFyZW50c2AgfCBgc3RyaW5nW10/YCB8IEFsbG93ZWQgcGFyZW50IGNvbW1hbmRzIHwKfCBgbm90QWxsb3dDaGlsZHJlbmAgfCBgc3RyaW5nW10/YCB8IERpc2FsbG93ZWQgY2hpbGQgY29tbWFuZHMgfAp8IGBzeW5jR3JvdXBJZGAgfCBgYm9vbGVhbj9gIHwgU3luYyBncm91cCBJRCBhY3Jvc3MgY2hpbGRyZW4gfAp8IGBkaXNhYmxlQ29weWAgfCBgYm9vbGVhbj9gIHwgUHJldmVudCBjb3B5IHwKfCBgZGlzYWJsZURlbGV0ZWAgfCBgYm9vbGVhbj9gIHwgUHJldmVudCBkZWxldGUgfAp8IGByZXF1aXJlQ2hpbGRyZW5gIHwgYGJvb2xlYW4/YCB8IFdoZXRoZXIgYSBjaGlsZCBjb21tYW5kIGlzIHJlcXVpcmVkIHwKfCBgcmVxdWlyZVBhcmVudGAgfCBgYm9vbGVhbj9gIHwgV2hldGhlciBhIHBhcmVudCBjb21tYW5kIGlzIHJlcXVpcmVkIHwKfCBgY2hpbGRyZW5Db21tYW5kYCB8IGBzdHJpbmc/YCB8IERlZmF1bHQgY29tbWFuZCB0eXBlIGZvciBjaGlsZHJlbiB8CgoqKlZhbGlkYXRpb24gcnVsZXM6KioKLSBgaWRgLCBgbmFtZWAsIGB2ZXJzaW9uYCwgYG1pbk11c2NhdFZlcnNpb25gIOKAlCByZXF1aXJlZCBub24tZW1wdHkgc3RyaW5ncwotIGBhdXRob3JgIOKAlCByZXF1aXJlZCBub24tZW1wdHkgc3RyaW5nCi0gYGRlc2NyaXB0aW9uYCDigJQgcmVxdWlyZWQgKGBzdHJpbmdgIG9yIGB7IGVuIChyZXF1aXJlZCksIGtvPywgamE/LCB6aD8sIHZpPywgdGg/LCBlcz8gfWApCi0gYGljb25zYCDigJQgU1ZHOiBzaW5nbGUgc3RyaW5nIHBhdGggZW5kaW5nIGluIGAuc3ZnYDsgUE5HL0pQRzogb2JqZWN0IHdpdGggYCIxNiJgLCBgIjQ4ImAsIGAiMTI4ImAgYWxsIHByZXNlbnQKLSBgdGFyZ2V0TW9kZWxzYCDigJQgYCJhbGwiYCBvciBhIG5vbi1lbXB0eSBhcnJheSBvZiByb2JvdCBtb2RlbCBJRCBzdHJpbmdzIChhdCBsZWFzdCBvbmUgb2YgYHRhcmdldE1vZGVsc2AgLyBgdGFyZ2V0Q2F0ZWdvcnlzYCByZXF1aXJlZCkKLSBgdGFyZ2V0Q2F0ZWdvcnlzYCDigJQgYCJhbGwiYCBvciBhIG5vbi1lbXB0eSBhcnJheSBvZiBgIm1hbmlwdWxhdGUiIHwgImFtciIgfCAicmJ5MSIgfCAidmlzaW9uImAgKGF0IGxlYXN0IG9uZSBvZiBgdGFyZ2V0TW9kZWxzYCAvIGB0YXJnZXRDYXRlZ29yeXNgIHJlcXVpcmVkKQotIGBjb250cmlidXRlc2Ag4oCUIHRoZSBwbHVnaW4ncyBzY3JlZW5zOyB3aGVuIHByZXNlbnQgaXQgbXVzdCBjb250YWluIGF0IGxlYXN0IG9uZSBgdG9vbGJhcmAgZW50cnkuIExlYXZlIGl0IG91dCAob3IgYFtdYCkgZm9yIGEgYmFja2VuZC1vbmx5IHBsdWdpbjogbm8gVUkgaXMgYnVpbHQsIGFuZCBOb2RlLmpzIGlzIG5vdCBuZWVkZWQgdG8gYnVpbGQgaXQKLSBgdWlgIOKAlCBlYWNoIGNvbnRyaWJ1dGlvbiBtdXN0IGhhdmUgYSB1bmlxdWUgdmFsdWUKLSBgY29tbWFuZEluZm9gIOKAlCByZXF1aXJlZCB3aGVuIGBwb2ludGAgaXMgYCJwcm9ncmFtLnBhbmVsImAKLSBgcG9ydHNgIOKAlCBvcHRpb25hbCBgbnVtYmVyW11gOyBldmVyeSBwb3J0IG11c3QgYmUgd2l0aGluIGAyODYwMC0yODk5OWAKICBhbmQgbXVzdCBub3QgYmUgYSByZXNlcnZlZCByb2JvdC9pbmR1c3RyaWFsL2ludGVybmFsIHBvcnQKLSBgdmFyaWFibGVzYCDigJQgb3B0aW9uYWwgYXJyYXkgb2YgYHsgbmFtZSwgdHlwZSwgaW5pdCwgZGVzY3JpcHRpb24/IH1gOgogIC0gYG5hbWVgIOKAlCBtdXN0IHN0YXJ0IHdpdGggYFJCUF9gLCB0aGVuIGxldHRlcnMvZGlnaXRzL3VuZGVyc2NvcmU7IHVuaXF1ZSBwZXIgcGx1Z2luCiAgLSBgdHlwZWAg4oCUIGAibnVtYmVyIiB8ICJzdHJpbmciIHwgImFycmF5ImAKICAtIGBpbml0YCDigJQgcmVxdWlyZWQgaW5pdGlhbCB2YWx1ZSwgbXVzdCBtYXRjaCBgdHlwZWAKICAtIGBkZXNjcmlwdGlvbmAg4oCUIG9wdGlvbmFsIGBzdHJpbmdgIG9yIGkxOG4gb2JqZWN0IChgZW5gIHJlcXVpcmVkIGluIG9iamVjdCBmb3JtKQoKYG11c2NhdC1wayBidWlsZGAgdGhyb3dzIG9uIGFueSB2YWxpZGF0aW9uIGVycm9yLiBgbXVzY2F0LXBrIGRldmAgcHJpbnRzCndhcm5pbmdzIOKAlCBleGNlcHQgYHZhcmlhYmxlc2AgZXJyb3JzIChlLmcuIGEgbmFtZSB3aXRob3V0IHRoZSBgUkJQX2AgcHJlZml4KSwKd2hpY2ggYXJlIGhhcmQgZXJyb3JzIGluIGBkZXZgIC8gYGRldjpiYWNrYCB0b28uCgoqKkJhY2tlbmQgcG9ydCBydWxlczoqKgotIERlY2xhcmUgYSBwb3J0IG9ubHkgaWYgeW91ciBiYWNrZW5kIG9wZW5zIGEgVENQIHNlcnZlci9saXN0ZW5lci4KLSAqKkV2ZXJ5IGxpc3RlbmluZyBUQ1AgcG9ydCBtdXN0IGJlIGRlY2xhcmVkLioqIGBtdXNjYXQtcGsgZGV2YCBhbmQKICBgbXVzY2F0LXBrIGRldjpiYWNrYCB3YXRjaCB0aGUgYmFja2VuZCBhbmQgc3RvcCBpdCB0aGUgbW9tZW50IGl0IG9wZW5zIGEgcG9ydAogIHRoYXQgaXMgbm90IGluIGBwb3J0c2AuIEEgcG9ydCBvdXRzaWRlIGAyODYwMC0yODk5OWAgY2FuJ3QgYmUgZGVjbGFyZWQsIHNvIGl0CiAgbXVzdCBub3QgYmUgb3BlbmVkIGVpdGhlciDigJQgcGlja2luZyBlLmcuIGA1NTAwYCBpcyBub3QgYSB3YXkgYXJvdW5kIHRoZSBydWxlLgogIEl0IHdvdWxkIGVzY2FwZSB0aGlzIGNoZWNrICphbmQqIHRoZSByb2JvdCdzIGluc3RhbGwtdGltZSBjb25mbGljdCBjaGVjaywgYW5kCiAgb25seSBjb2xsaWRlIG9uY2UgaXQncyBydW5uaW5nIG9uIGEgcm9ib3QuCi0gUmVzZXJ2ZWQgcG9ydHMgaW5jbHVkZSBgNTAyYCwgYDIyMjJgLCBgNDg0MGAsIGA1MTcwLTUxNzlgLCBgODAwMC04OTk5YCwKICBgMTAwMDBgLCBgMzAwMDRgLCBgMzQ5NjRgLCBgNDQ4MThgLCBgNTAwMDAtNTAwMDVgLCBhbmQgYDUwMDUxYC4KLSBUaGUgcm9ib3QgcmVqZWN0cyBpbnN0YWxsYXRpb24gKEhUVFAgNDA5KSBpZiBhIGRlY2xhcmVkIHBvcnQgaXMgcmVzZXJ2ZWQsCiAgb3V0IG9mIHJhbmdlLCBvciBhbHJlYWR5IGNsYWltZWQgYnkgYW5vdGhlciBlbmFibGVkIHBsdWdpbi4KCioqUmVhY2hpbmcgeW91ciBiYWNrZW5kJ3MgcG9ydHMgZHVyaW5nIGRldmVsb3BtZW50OioqCi0gRGVjbGFyZWQgcG9ydHMgYXJlIHB1Ymxpc2hlZCB0byBgMTI3LjAuMC4xYCBvbiB5b3VyIG1hY2hpbmUsIHNvCiAgYGN1cmwgaHR0cDovLzEyNy4wLjAuMToyODYwMGAgd29ya3MgZnJvbSB0aGUgaG9zdCBvbiBtYWNPUywgV2luZG93cywgYW5kIExpbnV4LgotIE9uIG5hdGl2ZSBMaW51eCB0aGUgZGV2IGNvbnRhaW5lciB1c2VzIGhvc3QgbmV0d29ya2luZywgc28gdGhlIHBvcnRzIGFyZSBvbgogIHRoZSBob3N0IGFscmVhZHkuCi0gSWYgYSBkZWNsYXJlZCBwb3J0IGlzIGFscmVhZHkgdGFrZW4gb24geW91ciBtYWNoaW5lLCBgbXVzY2F0LXBrIGRldmAgd2FybnMgYW5kCiAgc2tpcHMgcHVibGlzaGluZyB0aGF0IG9uZSDigJQgdGhlIGJhY2tlbmQgc3RpbGwgbGlzdGVucyBpbnNpZGUgdGhlIGNvbnRhaW5lci4KCi0tLQoKIyMgTG9jYWxpemVkIGRvY3VtZW50YXRpb24KCllvdSBjYW4gc2hpcCBwZXItbGFuZ3VhZ2UgUkVBRE1FIGZpbGVzIGFsb25nc2lkZSB0aGUgbWFpbiBgUkVBRE1FLm1kYC4gUGxhY2UgdGhlbSBpbiB0aGUgcHJvamVjdCByb290OgoKYGBgClJFQURNRS5tZCAgICAgICAgIyBkZWZhdWx0IC8gRW5nbGlzaCBmYWxsYmFjawpSRUFETUUua28ubWQgICAgICMgS29yZWFuClJFQURNRS5lbi5tZCAgICAgIyBleHBsaWNpdCBFbmdsaXNoIChvcHRpb25hbCkKUkVBRE1FLmphLm1kICAgICAjIEphcGFuZXNlCmBgYAoKQWxsIGBSRUFETUUqLm1kYCBmaWxlcyBmb3VuZCBhdCB0aGUgcHJvamVjdCByb290IGFyZSBhdXRvbWF0aWNhbGx5IGNvcGllZCB0byBgZGlzdC9gIG9uCmBtdXNjYXQtcGsgYnVpbGRgLiBNdXNjYXQgZGlzcGxheXMgdGhlIGZpbGUgbWF0Y2hpbmcgdGhlIHVzZXIncyBsb2NhbGUsCmZhbGxpbmcgYmFjayB0byBgUkVBRE1FLm1kYCBpZiBub25lIG1hdGNoZXMuCgotLS0KCiMjIEluc3RhbGxpbmcgUHl0aG9uIGRlcGVuZGVuY2llcwoKQWRkIGFueSBwYWNrYWdlIHdpdGggYW4gb3B0aW9uYWwgdmVyc2lvbiBwaW4gdG8gYHJlcXVpcmVtZW50cy50eHRgOgoKYGBgCnJhaW5ib3ctcmItc2RrCnJhaW5ib3ctcmItZmxhdC1idWZmZXJzCm51bXB5PT0xLjI2LjQKb3BlbmN2LXB5dGhvbgpgYGAKClJ1biBgbXVzY2F0LXBrIGRldmAgb3IgYG11c2NhdC1wayBkZXY6YmFja2Ag4oCUIGRlcGVuZGVuY2llcyBhcmUgaW5zdGFsbGVkIGF1dG9tYXRpY2FsbHkKaW5zaWRlIHRoZSBkZXYgY29udGFpbmVyIChgcGlwIGluc3RhbGwgLXIgcmVxdWlyZW1lbnRzLnR4dGApIG9uIGV2ZXJ5IHN0YXJ0dXAuIE5vCmxvY2FsIFB5dGhvbiBpcyByZXF1aXJlZCBmb3IgdGhpcy4KCmBtdXNjYXQtcGsgZGV2OmJhY2tgIGFsc28gYmVzdC1lZmZvcnQgY3JlYXRlcy9yZWZyZXNoZXMgYSBsb2NhbCBgLnZlbnZgIGluIHRoZQpiYWNrZ3JvdW5kICh2aWEgYHV2YCBpZiBhdmFpbGFibGUsIGVsc2UgeW91ciBzeXN0ZW0gUHl0aG9uKSB3aXRoIHRoZSBzYW1lIGRlcHMg4oCUCnB1cmVseSBzbyB5b3VyIGVkaXRvciAocHlsaW50LCBweXJpZ2h0LCBteXB5LCAuLi4pIGNhbiByZXNvbHZlIGltcG9ydHMgYW5kIGxpbnQKY29ycmVjdGx5LiBJdCdzIG5vdCB1c2VkIHRvIHJ1biB0aGUgYmFja2VuZDsgRG9ja2VyIGlzIHRoZSBhY3R1YWwgZXhlY3V0aW9uCmVudmlyb25tZW50LCBzbyB0aGlzIHN0ZXAgaXMgc2lsZW50bHkgc2tpcHBlZCBpZiBubyBsb2NhbCBQeXRob24gdG9vbGNoYWluIGlzCmF2YWlsYWJsZS4gUG9pbnQgeW91ciBlZGl0b3IncyBQeXRob24gaW50ZXJwcmV0ZXIgYXQgYC52ZW52YC4KCmBtdXNjYXQtcGsgc2RrIHVwZGF0ZWAgYWxzbyByZWZyZXNoZXMgYC52ZW52YCBpbiBwbGFjZSBpZiBvbmUgYWxyZWFkeSBleGlzdHMsIHNvCnlvdXIgZWRpdG9yIHBpY2tzIHVwIHRoZSBuZXcgYHJhaW5ib3ctcmItc2RrYCB2ZXJzaW9uIGltbWVkaWF0ZWx5LgoKPiBgbXVzY2F0LXBrIGJ1aWxkYCBvbmx5ICoqcGlucyoqIHZlcnNpb25zIGluIGByZXF1aXJlbWVudHMudHh0YCDigJQgaXQgZG9lcyBub3QgcnVuIGBwaXAgaW5zdGFsbGAgKHRoZSByb2JvdCBpbnN0YWxscyB0aGVtIGF0IGxvYWQgdGltZSkuCgotLS0KCiMjIFN3aXRjaGluZyBiYWNrZW5kIHR5cGUKCmBgYGJhc2gKbXVzY2F0LXBrIHR5cGUgY2hhbmdlICAgICAgICAgICAgICAgICAjIGludGVyYWN0aXZlCm11c2NhdC1wayB0eXBlIGNoYW5nZSAtLXRvIGNwcCAgICAgICAgIyDihpIgQysrCm11c2NhdC1wayB0eXBlIGNoYW5nZSAtLXRvIHJvczIgICAgICAgIyDihpIgUk9TMiAocmNscHkgLyBQeXRob24pCm11c2NhdC1wayB0eXBlIGNoYW5nZSAtLXRvIHJvczItY3BwICAgIyDihpIgUk9TMiAocmNsY3BwIC8gQysrKQptdXNjYXQtcGsgdHlwZSBjaGFuZ2UgLS10byBweXRob24gICAgICMg4oaSIFB5dGhvbgpgYGAKCj4gRXhpc3RpbmcgYmFja2VuZCBkaXJzIChgcm9zMl93cy9gLCBgY3BwL2ApIGFyZSBub3QgZGVsZXRlZCB3aGVuIHN3aXRjaGluZyBhd2F5LiBSZW1vdmUgdGhlbSBtYW51YWxseSBpZiBubyBsb25nZXIgbmVlZGVkLgoKPiBTd2l0Y2hpbmcgYmV0d2VlbiBhIFB5dGhvbiBhbmQgYSBDKysgYmFja2VuZCBhc2tzIHdoZXRoZXIgdG8gcmVwbGFjZSB0aGlzIFJFQURNRSB3aXRoIHRoZSBtYXRjaGluZyBvbmUgKHRoZSBvbGQgZmlsZSBpcyBrZXB0IGFzIGBSRUFETUUubWQuYmFrYCkuIEFkZCBgLS1yZWFkbWVgIHRvIGFuc3dlciB5ZXMgd2l0aG91dCB0aGUgcHJvbXB0LgoKLS0tCgojIyBBSSBjb2RpbmcgYXNzaXN0YW50cyAoTUNQKQoKSWYgeW91IGJ1aWxkIHlvdXIgcGx1Z2luIHdpdGggYW4gQUkgYXNzaXN0YW50IChDbGF1ZGUgQ29kZSwgQ29kZXgsIOKApiksIGdpdmUgaXQKZ3JvdW5kZWQga25vd2xlZGdlIG9mIHRoZSBNdXNjYXQgVUkgY29tcG9uZW50cywgZGVzaWduIHRva2VucywgYW5kIFNESyBpbnN0ZWFkIG9mCmxldHRpbmcgaXQgZ3Vlc3MuIGBtdXNjYXQtcGsgbWNwYCBpcyBhbiBNQ1Agc2VydmVyIGV4cG9zaW5nOgoKLSBgbGlzdF9jb21wb25lbnRzYCAvIGBnZXRfY29tcG9uZW50X3Byb3BzYCAvIGBnZXRfY29tcG9uZW50X2V4YW1wbGVgIOKAlCBldmVyeQogIGBAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWkvcmVhY3RgIGNvbXBvbmVudCB3aXRoIGl0cyByZWFsIHByb3BzIGFuZCBhIHdvcmtpbmcKICBTdG9yeWJvb2sgZXhhbXBsZS4KLSBgbGlzdF9kZXNpZ25fdG9rZW5zYCAvIGBzZWFyY2hfZGVzaWduX3Rva2Vuc2Ag4oCUIHRoZSBUYWlsd2luZCBjbGFzc2VzIHRvIHVzZQogIChgYmctYmctKmAsIGB0ZXh0LWZnLSpgLCBgdHlwby0qYCwg4oCmKSBzbyB5b3VyIFVJIG1hdGNoZXMgdGhlIGhvc3QgdGhlbWUuCi0gYHNlYXJjaF9yYl9zZGtgIOKAlCBob3cgdG8gdXNlIGB1c2VSYigpYCwgYHJiLipgLCBgdXNlUmJGb3JtRGF0YWAvYHVzZVJiU2F2ZWAsIGFuZAogIHRoZSBiYWNrZW5kIHJ1bnRpbWVzLgotIGBsaXN0X3JiX3Nka2AgLyBgZ2V0X3JiX3Nka19hcGlgIOKAlCB0aGUgaW5zdGFsbGVkIGByYWluYm93LXJiLXNka2AgKFB5dGhvbgogIGJhY2tlbmQpIGNsYXNzZXMgYW5kIHNpZ25hdHVyZXM7IHdpdGggYGxhbmc6ICJjcHAiYCwgdGhlIEMrKyBTREsgaGVhZGVycwogIChgcmFpbmJvdy1yYi1zZGstZGV2YCwgcmVhZCBvdXQgb2YgdGhlIGBtdXNjYXQtcGtgIGNwcCBkZXYgaW1hZ2Ug4oCUIGJ1aWxkIGl0CiAgb25jZSB3aXRoIGBtdXNjYXQtcGsgZGV2OmJhY2tgKS4KLSBgY2hlY2tfcHJvamVjdGAg4oCUIHdoYXQgdGhpcyBwcm9qZWN0IG11c3QgY2hhbmdlIGZvciB0aGUgcGx1Z2luLXVpIGl0IGhhcwogIGluc3RhbGxlZCAob2xkIEFQSXMgc3VjaCBhcyBgY29ubmVjdChBcHApYCBvciBgU2xpZGVyYCwgYSBgdml0ZS5jb25maWdgIHdpdGhvdXQKICB0aGUgYG11c2NhdCgpYCBwcmVzZXQsIGB0c2NgIGVycm9ycyksIHRoZSBzYW1lIGxpc3QgYG11c2NhdC1wayB1cGRhdGVgIHByaW50cy4KICBBc2sgdGhlIGFzc2lzdGFudCB0byBmaXggdGhlIHByb2plY3QgYWZ0ZXIgYW4gdXBkYXRlOyBpdCByZS1jaGVja3MgdW50aWwgY2xlYW4uCgoqKkJyb3dzZSB0aGUgY29tcG9uZW50cyBsaXZlKiogd2l0aCBgbXVzY2F0LXBrIHN0b3J5Ym9va2AuCgpgbXVzY2F0LXBrIG5ld2AgYWxzbyB3cml0ZXMgYEFHRU5UUy5tZGAgKHJlYWQgYnkgQ29kZXgsIEN1cnNvciwgR2VtaW5pIENMSSwgQ29waWxvdCkKYW5kIGEgYENMQVVERS5tZGAgdGhhdCBpbXBvcnRzIGl0OiB0aGUgVUkgcnVsZXMgKHBsdWdpbi11aSBjb21wb25lbnRzIGluc3RlYWQgb2YKbmF0aXZlIGA8c2VsZWN0PmAvYDxpbnB1dD5gL2A8YnV0dG9uPmAsIGRlc2lnbiB0b2tlbnMgZm9yIGNvbG9ycykgZm9yIGFzc2lzdGFudHMgdGhhdApkbyBub3QgY2FsbCB0aGUgTUNQIHRvb2xzIG9uIHRoZWlyIG93bi4gQWRkIHlvdXIgb3duIHByb2plY3Qgbm90ZXMgdGhlcmUuCgojIyMgUmVnaXN0ZXIgdGhlIHNlcnZlcgoKKipDbGF1ZGUgQ29kZSoqIOKAlCBhIGAubWNwLmpzb25gIGlzIGFscmVhZHkgc2NhZmZvbGRlZCBhdCB5b3VyIHBsdWdpbiByb290LCBzbwppdCB3b3JrcyBvdXQgb2YgdGhlIGJveDoKCmBgYGpzb24KewogICJtY3BTZXJ2ZXJzIjogewogICAgIm11c2NhdCI6IHsKICAgICAgImNvbW1hbmQiOiAibXVzY2F0LXBrIiwKICAgICAgImFyZ3MiOiBbIm1jcCJdCiAgICB9CiAgfQp9CmBgYAoKKipDb2RleCoqIOKAlCByZWdpc3RlciBvbmNlIHdpdGg6CgpgYGBiYXNoCm11c2NhdC1wayBtY3AgLS1pbnN0YWxsIGNvZGV4CmBgYAoKVGhpcyBhcHBlbmRzIHRoZSBzZXJ2ZXIgdG8gYH4vLmNvZGV4L2NvbmZpZy50b21sYCAoaWRlbXBvdGVudCDigJQgc2FmZSB0byBydW4KYWdhaW4pLiBFcXVpdmFsZW50IG1hbnVhbCBjb25maWc6CgpgYGB0b21sClttY3Bfc2VydmVycy5tdXNjYXRdCmNvbW1hbmQgPSAibXVzY2F0LXBrIgphcmdzID0gWyJtY3AiXQpgYGAKCkFueSBvdGhlciBNQ1AgY2xpZW50IHdvcmtzIHRvbyDigJQgaXQncyBhIHN0YW5kYXJkIHN0ZGlvIE1DUCBzZXJ2ZXIgc3RhcnRlZCB3aXRoCmBtdXNjYXQtcGsgbWNwYC4gSWYgYG11c2NhdC1wa2AgaXNuJ3Qgb24gdGhlIGNsaWVudCdzIFBBVEgsIHVzZSBpdHMgYWJzb2x1dGUgcGF0aAooYHdoaWNoIG11c2NhdC1wa2ApIGFzIGBjb21tYW5kYC4KCi0tLQoKIyMgU2hpcHBpbmcKCmBgYGJhc2gKbXVzY2F0LXBrIGJ1aWxkICAgICAgICAgICAgIyBidWlsZCArIFpJUAptdXNjYXQtcGsgYnVpbGQgLS1uby16aXAgICAjIGJ1aWxkIG9ubHksIG5vIFpJUApgYGAKCj4gQnVpbGRpbmcgdGhlIG90aGVyIGFyY2ggKGUuZy4gYXJtNjQgb24gYW4gYW1kNjQgUEMpIHJ1bnMgaW4gYW4gZW11bGF0ZWQgY29udGFpbmVyIGZvcgo+IEMrKyBiYWNrZW5kcy4gRG9ja2VyIERlc2t0b3AgaGFzIGl0IGJ1aWx0IGluOyBvbiBMaW51eCBlbmFibGUgaXQgb25jZSB3aXRoCj4gYGRvY2tlciBydW4gLS1wcml2aWxlZ2VkIC0tcm0gdG9uaXN0aWlnaS9iaW5mbXQgLS1pbnN0YWxsIGFsbGAsIG9yIHBhc3MgYC0tYXJjaGAgZm9yIG9uZSBhcmNoLgoKLSBCdWlsZHMgYHVpL2NvbnRlbnQudHN4YCDihpIgYGRpc3QvY29udGVudC5qc2AgKG1pbmlmaWVkKQotIFBpbnMgYHJlcXVpcmVtZW50cy50eHRgIHRvIGxhdGVzdCB2ZXJzaW9ucyAoc3RhYmxlLW9ubHkgb24gYG1haW5gIGJyYW5jaCkKLSBDb3BpZXMgYGFzc2V0cy9gLCBgbWFuaWZlc3QuanNvbmAsIGBSRUFETUUqLm1kYCwgYHB5L2AsIGFuZCBgcmVxdWlyZW1lbnRzLnR4dGAgaW50byBgZGlzdC9gCi0gUk9TMjogcnVucyBgY29sY29uIGJ1aWxkYCBpbnNpZGUgdGhlIEphenp5IGNvbnRhaW5lcjsgaW5jbHVkZXMgYHJvczJfd3MvaW5zdGFsbC9gCi0gT3V0cHV0OiBgX19QTFVHSU5fRElSX18te3ZlcnNpb259LnppcGAKClpJUCBsYXlvdXQ6CgpgYGAKX19QTFVHSU5fRElSX18tMS4wLjAuemlwCuKUnOKUgCBkaXN0LwrilIIgICDilJzilIAgY29udGVudC5qcyAgICAgICAgIyBidWlsdCBVSQrilIIgICDilJzilIAgbWFuaWZlc3QuanNvbgrilIIgICDilJzilIAgYXNzZXRzLwrilIIgICDilJzilIAgUkVBRE1FLm1kCuKUgiAgIOKUnOKUgCBSRUFETUUua28ubWQgICAgICAjIGlmIHByZXNlbnQK4pSCICAg4pSc4pSAIG1haW4ucHkgICAgICAgICAgICMgZnJvbSBweS8K4pSCICAg4pSU4pSAIHJlcXVpcmVtZW50cy50eHQgICMgcGlubmVkCuKUlOKUgCByb3MyX3dzL2luc3RhbGwvICAgICAgIyBST1MyIG9ubHkKYGBgCgotLS0KCiMjIEFsbCBjb21tYW5kcwoKYGBgYmFzaAptdXNjYXQtcGsgZGV2ICAgICAgICAjIFVJICsgYmFja2VuZAptdXNjYXQtcGsgZGV2OnVpICAgICAjIFVJIHByZXZpZXcgb25seSAocHJldmlldy1ob3N0KQptdXNjYXQtcGsgZGV2OmJhY2sgICAjIGJhY2tlbmQgb25seSAoUHl0aG9uOiB3YXRjaGZpbGVzIC8gUk9TMjogRG9ja2VyKQptdXNjYXQtcGsgYnVpbGQgICAgICAjIGJ1aWxkIOKGkiBkaXN0LyArIGRpc3RyaWJ1dGFibGUgWklQICgtLW5vLXppcCB0byBza2lwKQptdXNjYXQtcGsgc3Rvcnlib29rICAjIGJyb3dzZSB0aGUgcmItY29tcG9uZW50cyBVSSBsaWJyYXJ5IGluIGEgYnJvd3NlcgptdXNjYXQtcGsgbWNwICAgICAgICAjIE1DUCBzZXJ2ZXIgZm9yIEFJIGFzc2lzdGFudHMgKGNvbXBvbmVudHMvdG9rZW5zL1NESyBkb2NzKQpgYGAKCmBgYGJhc2gKbXVzY2F0LXBrIHR5cGUgY2hhbmdlICAgICMgc3dpdGNoIGJhY2tlbmQgdHlwZQptdXNjYXQtcGsgc2RrIGxpc3QgICAgICAgIyBzaG93IGN1cnJlbnQgUHl0aG9uIFNESyB2ZXJzaW9uCm11c2NhdC1wayBzZGsgdXBkYXRlICAgICAjIHVwZGF0ZSBQeXRob24gU0RLIHRvIGxhdGVzdAptdXNjYXQtcGsgdXBkYXRlICAgICAgICAgIyB1cGRhdGUgbXVzY2F0LXBsdWdpbi1raXQgaXRzZWxmCm11c2NhdC1wayB1bmluc3RhbGwgICAgICAjIHJlbW92ZSBtdXNjYXQtcGsgaXRzZWxmCmBgYAo=","common/assets/icon.svg":"PHN2ZyB3aWR0aD0iMjU2IiBoZWlnaHQ9IjI1NiIgdmlld0JveD0iMCAwIDI1NiAyNTYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPGRlZnM+CiAgICA8bGluZWFyR3JhZGllbnQgaWQ9ImJnIiB4MT0iMzYiIHkxPSIyOCIgeDI9IjIyMCIgeTI9IjIyOCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgogICAgICA8c3RvcCBzdG9wLWNvbG9yPSIjOEI1Q0Y2Ii8+CiAgICAgIDxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzVCMjFCNiIvPgogICAgPC9saW5lYXJHcmFkaWVudD4KICAgIDxsaW5lYXJHcmFkaWVudCBpZD0iZ3JhcGUiIHgxPSI5MiIgeTE9Ijc0IiB4Mj0iMTY4IiB5Mj0iMTc4IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CiAgICAgIDxzdG9wIHN0b3AtY29sb3I9IiNEOEI0RkUiLz4KICAgICAgPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjQTg1NUY3Ii8+CiAgICA8L2xpbmVhckdyYWRpZW50PgogIDwvZGVmcz4KCiAgPHJlY3QgeD0iMTYiIHk9IjE2IiB3aWR0aD0iMjI0IiBoZWlnaHQ9IjIyNCIgcng9IjUyIiBmaWxsPSJ1cmwoI2JnKSIvPgoKICA8IS0tIHBsdWdpbiBicmFja2V0cyAtLT4KICA8cGF0aCBkPSJNNzIgODRINTZDNDcuMTYzNCA4NCA0MCA5MS4xNjM0IDQwIDEwMFYxMTYiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMTIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgogIDxwYXRoIGQ9Ik0xODQgODRIMjAwQzIwOC44MzcgODQgMjE2IDkxLjE2MzQgMjE2IDEwMFYxMTYiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMTIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgogIDxwYXRoIGQ9Ik03MiAxNzJINTZDNDcuMTYzNCAxNzIgNDAgMTY0LjgzNyA0MCAxNTZWMTQwIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjEyIiBzdHJva2UtbGluZWNhcD0icm91bmQiLz4KICA8cGF0aCBkPSJNMTg0IDE3MkgyMDBDMjA4LjgzNyAxNzIgMjE2IDE2NC44MzcgMjE2IDE1NlYxNDAiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMTIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgoKICA8IS0tIGdyYXBlIHN0ZW0gKyBsZWFmIC0tPgogIDxwYXRoIGQ9Ik0xMjggNzNDMTI4IDU5IDEzNyA0OCAxNTEgNDQiIHN0cm9rZT0iI0YzRThGRiIgc3Ryb2tlLXdpZHRoPSIxMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+CiAgPHBhdGggZD0iTTE0MiA1MUMxNTEgMzkgMTY5IDM5IDE3OSA1MEMxNjUgNjAgMTUxIDYyIDE0MiA1MVoiIGZpbGw9IiNDNEI1RkQiLz4KCiAgPCEtLSBtdXNjYXQgZ3JhcGUgY2x1c3RlciAtLT4KICA8Y2lyY2xlIGN4PSIxMDYiIGN5PSI5MSIgcj0iMTgiIGZpbGw9InVybCgjZ3JhcGUpIi8+CiAgPGNpcmNsZSBjeD0iMTMyIiBjeT0iODgiIHI9IjE4IiBmaWxsPSJ1cmwoI2dyYXBlKSIvPgogIDxjaXJjbGUgY3g9IjE1OCIgY3k9IjkxIiByPSIxOCIgZmlsbD0idXJsKCNncmFwZSkiLz4KICA8Y2lyY2xlIGN4PSI5NCIgY3k9IjExOSIgcj0iMTgiIGZpbGw9InVybCgjZ3JhcGUpIi8+CiAgPGNpcmNsZSBjeD0iMTIwIiBjeT0iMTE2IiByPSIxOCIgZmlsbD0idXJsKCNncmFwZSkiLz4KICA8Y2lyY2xlIGN4PSIxNDYiIGN5PSIxMTYiIHI9IjE4IiBmaWxsPSJ1cmwoI2dyYXBlKSIvPgogIDxjaXJjbGUgY3g9IjE3MiIgY3k9IjExOSIgcj0iMTgiIGZpbGw9InVybCgjZ3JhcGUpIi8+CiAgPGNpcmNsZSBjeD0iMTA3IiBjeT0iMTQ1IiByPSIxOCIgZmlsbD0idXJsKCNncmFwZSkiLz4KICA8Y2lyY2xlIGN4PSIxMzMiIGN5PSIxNDQiIHI9IjE4IiBmaWxsPSJ1cmwoI2dyYXBlKSIvPgogIDxjaXJjbGUgY3g9IjE1OSIgY3k9IjE0NSIgcj0iMTgiIGZpbGw9InVybCgjZ3JhcGUpIi8+CiAgPGNpcmNsZSBjeD0iMTIwIiBjeT0iMTcwIiByPSIxOCIgZmlsbD0idXJsKCNncmFwZSkiLz4KICA8Y2lyY2xlIGN4PSIxNDYiIGN5PSIxNzAiIHI9IjE4IiBmaWxsPSJ1cmwoI2dyYXBlKSIvPgogIDxjaXJjbGUgY3g9IjEzMyIgY3k9IjE5MyIgcj0iMTgiIGZpbGw9InVybCgjZ3JhcGUpIi8+CgogIDwhLS0gY2VudGVyIHBsdWdpbiBnbHlwaCAtLT4KICA8cGF0aCBkPSJNMTIyIDExOVYxMDlDMTIyIDEwMy40NzcgMTI2LjQ3NyA5OSAxMzIgOTlIMTM2QzE0MS41MjMgOTkgMTQ2IDEwMy40NzcgMTQ2IDEwOVYxMTkiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iOCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+CiAgPHJlY3QgeD0iMTE2IiB5PSIxMTgiIHdpZHRoPSIzNiIgaGVpZ2h0PSIzNCIgcng9IjEwIiBmaWxsPSJ3aGl0ZSIvPgogIDxwYXRoIGQ9Ik0xMjcgMTUyVjE2MyIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSI4IiBzdHJva2UtbGluZWNhcD0icm91bmQiLz4KICA8cGF0aCBkPSJNMTQxIDE1MlYxNjMiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iOCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+Cjwvc3ZnPgo=","common/manifest.json":"ewogICJpZCI6ICJfX1BMVUdJTl9JRF9fIiwKICAibmFtZSI6ICJfX1BMVUdJTl9OQU1FX18iLAogICJ2ZXJzaW9uIjogIjEuMC4wIiwKICAibWluTXVzY2F0VmVyc2lvbiI6ICIxLjAuMCIsCiAgImF1dGhvciI6ICJfX1BMVUdJTl9BVVRIT1JfXyIsCiAgImVtYWlsIjogIl9fUExVR0lOX0VNQUlMX18iLAogICJkZXNjcmlwdGlvbiI6IHsKICAgICJrbyI6ICIiLAogICAgImVuIjogIiIKICB9LAogICJpY29ucyI6ICJhc3NldHMvaWNvbi5zdmciLAogICJ0YXJnZXRNb2RlbHMiOiAiYWxsIiwKICAidGFyZ2V0Q2F0ZWdvcnlzIjogImFsbCIsCiAgImNvbnRyaWJ1dGVzIjogWwogICAgewogICAgICAicG9pbnQiOiAidG9vbGJhciIsCiAgICAgICJpY29uIjogImFzc2V0cy9pY29uLnN2ZyIsCiAgICAgICJsYWJlbCI6IHsgImtvIjogIl9fUExVR0lOX05BTUVfXyIsICJlbiI6ICJfX1BMVUdJTl9OQU1FX18iIH0sCiAgICAgICJ1aSI6ICJjb250ZW50IiwKICAgICAgIm9wZW5zIjogInBvcG92ZXIiCiAgICB9CiAgXSwKICAidmFyaWFibGVzIjogW10sCiAgInJ1bnRpbWUiOiB7ICJ0eXBlIjogIl9fUlVOVElNRV9UWVBFX18iLCAiZW50cnkiOiAibWFpbi5weSIgfQp9Cg==","common/package.json":"ewogICJuYW1lIjogIl9fUExVR0lOX0lEX18iLAogICJ2ZXJzaW9uIjogIjEuMC4wIiwKICAicHJpdmF0ZSI6IHRydWUsCiAgInR5cGUiOiAibW9kdWxlIiwKICAiZGVwZW5kZW5jaWVzIjogewogICAgIkByYWluYm93LXJvYm90aWNzL3BsdWdpbi11aSI6ICJfX1JCX1ZFUlNJT05fXyIKICB9LAogICJkZXZEZXBlbmRlbmNpZXMiOiB7CiAgICAiQHRhaWx3aW5kY3NzL3ZpdGUiOiAiXjQuMS4wIiwKICAgICJAcmFpbmJvdy1yb2JvdGljcy9tdXNjYXQtcGx1Z2luLWtpdCI6ICJfX1JCX1ZFUlNJT05fXyIsCiAgICAiQHJhaW5ib3ctcm9ib3RpY3MvcHJldmlldy1ob3N0IjogIl9fUkJfVkVSU0lPTl9fIiwKICAgICJAdHlwZXMvcmVhY3QiOiAiXjE5LjAuMTAiLAogICAgIkB0eXBlcy9yZWFjdC1kb20iOiAiXjE5LjAuNCIsCiAgICAiQHZpdGVqcy9wbHVnaW4tcmVhY3QiOiAiXjQuMC4wIiwKICAgICJyZWFjdCI6ICJeMTkuMC4wIiwKICAgICJyZWFjdC1kb20iOiAiXjE5LjAuMCIsCiAgICAidGFpbHdpbmRjc3MiOiAiXjQuMS4wIiwKICAgICJ0eXBlc2NyaXB0IjogIl41LjguMCIsCiAgICAidml0ZSI6ICJeNi4wLjAiCiAgfQp9Cg==","common/py/main.py":"IiIiCk11c2NhdCBwbHVnaW4gYmFja2VuZCDigJQgX19QTFVHSU5fTkFNRV9fCgpPbi1yb2JvdCAoZGVmYXVsdCk6CiAgbXVzY2F0LXBrIGRldjpiYWNrCiAgcHl0aG9uIG1haW4ucHkKClJlbW90ZSBkZXYgKGZyb20geW91ciBsYXB0b3ApOgogIFNldCBlbnYgdmFycyBiZWZvcmUgcnVubmluZzoKICAgIE1VU0NBVF9ST0JPVF9IT1NUPTE5Mi4xNjguMS4xMDAKICAgIE1VU0NBVF9ST0JPVF9UT0tFTj08c2VydmljZSB0b2tlbj4gICAob3B0aW9uYWw7IG5lZWRlZCBvbmx5IHdoZW4gdGhlIHJvYm90J3MgbG9naW4gcG9saWN5IGlzIG9uKQogIFRoZW46IG11c2NhdC1wayBkZXY6YmFjawoKSGFuZGxlcnM6CiAgcGx1Z2luLnNlcnZlIC8gcGx1Z2luLnN1YnNjcmliZSAvIHBsdWdpbi5wdWJsaXNoICAtPiBwbHVnaW4gVUkgPC0+IGJhY2tlbmQgb25seQogIHBsdWdpbi5yb3V0ZXIub24gLyBzdWJzY3JpYmUgLyBlbWl0ICAgICAgICAgICAgICAgLT4gZXh0ZXJuYWwgZW5kcG9pbnRzCiAgICAoUkVTVCAvIFNvY2tldC5JTyAvIFRDUCAvIE1RVFQgLyBXZWJSVEMgYXQgY29tbW9uL3BsdWdpbi88cGx1Z2luX2lkPi88cGF0aD4pLgogICAgTmVlZHMgYSByb2JvdCBydW5uaW5nIHJhaW5ib3ctcmItc2RrID49IDAuMC45LmRldjU7IG9sZGVyIHJvYm90cyBoYXZlIG5vCiAgICBgcGx1Z2luLnJvdXRlcmAgKEF0dHJpYnV0ZUVycm9yKS4gU2VlIFJFQURNRSAiRXh0ZXJuYWwgZW5kcG9pbnRzIi4KIiIiCgppbXBvcnQgYXN5bmNpbwppbXBvcnQgb3MKZnJvbSB0eXBpbmcgaW1wb3J0IEFueQoKZnJvbSByYWluYm93LnJiX3NkayBpbXBvcnQgUkJNYW5pcHVsYXRlU0RLLCBSQlBsdWdpbkNhbGwKZnJvbSByYWluYm93LnJiX3Nkay5yYl9zZGtfY3BwIGltcG9ydCBDb25uZWN0T3B0aW9ucwoKClBMVUdJTl9OQU1FID0gIl9fUExVR0lOX05BTUVfXyIKCnBsdWdpbiA9IFJCUGx1Z2luQ2FsbCgpCm1hbmlwdWxhdGUgPSBSQk1hbmlwdWxhdGVTREsoKQoKCmRlZiByZWdpc3Rlcl9oYW5kbGVycygpOgogICAgIyBSZWdpc3RlciBoYW5kbGVycyBoZXJlIOKAlCBjYWxsZWQgYWZ0ZXIgY29ubmVjdCgpIHNvIHN1YnNjcmlwdGlvbnMgc3Vydml2ZQogICAgIyBzZXNzaW9uIHJlY29ubmVjdGlvbiBpbiByZW1vdGUtZGV2IG1vZGUuCgogICAgIyAtLS0gUGx1Z2luIFVJIDwtPiBiYWNrZW5kIChub3QgcmVhY2hhYmxlIGZyb20gb3V0c2lkZSBNdXNjYXQpIC0tLQoKICAgIEBwbHVnaW4uc3Vic2NyaWJlKCJldmVudCIpCiAgICBkZWYgb25fdWlfZXZlbnQocGF5bG9hZDogZGljdFtzdHIsIEFueV0gfCBOb25lID0gTm9uZSk6CiAgICAgICAgIiIiSGFuZGxlIG1lc3NhZ2VzIHB1Ymxpc2hlZCBmcm9tIHRoZSBwbHVnaW4gVUkgd2l0aCByYi5wdWIoImV2ZW50IiwgLi4uKS4iIiIKICAgICAgICBwcmludChmIlt7UExVR0lOX05BTUV9XSBldmVudDoiLCBwYXlsb2FkKQoKICAgIEBwbHVnaW4uc2VydmUoImdyaXAiKQogICAgZGVmIGdyaXAocGF5bG9hZDogZGljdFtzdHIsIEFueV0gfCBOb25lID0gTm9uZSk6CiAgICAgICAgIiIiSGFuZGxlIHRoZSBkZWZhdWx0IFVJIGJ1dHRvbjogcmIuYWN0aW9uKCJncmlwIiwgeyB3aWR0aCB9KS4iIiIKICAgICAgICB3aWR0aCA9IChwYXlsb2FkIG9yIHt9KS5nZXQoIndpZHRoIiwgMjApCiAgICAgICAgcHJpbnQoZiJbe1BMVUdJTl9OQU1FfV0gZ3JpcCByZXF1ZXN0ZWQ6IHdpZHRoPXt3aWR0aH0iKQogICAgICAgIHBsdWdpbi5wdWJsaXNoKCJzdGF0ZSIsIHsicmVhZHkiOiBUcnVlLCAibGFzdF9ncmlwX3dpZHRoIjogd2lkdGh9KQogICAgICAgIHJldHVybiB7Im9rIjogVHJ1ZSwgIndpZHRoIjogd2lkdGh9CgogICAgQHBsdWdpbi5zZXJ2ZSgidG9vbC9lY2hvIikKICAgIGRlZiBlY2hvKHBheWxvYWQ6IGRpY3Rbc3RyLCBBbnldIHwgTm9uZSA9IE5vbmUpOgogICAgICAgICIiIlNtYWxsIHF1ZXJ5IGV4YW1wbGUgY2FsbGFibGUgZnJvbSB0aGUgVUkgd2l0aCByYi5hY3Rpb24oInRvb2wvZWNobyIsIC4uLikuIiIiCiAgICAgICAgcmV0dXJuIHsiZWNobyI6IHBheWxvYWQsICJwbHVnaW4iOiBQTFVHSU5fTkFNRX0KCiAgICAjIC0tLSBFeHRlcm5hbCBlbmRwb2ludHMgKFJFU1QgLyBTb2NrZXQuSU8gLyBUQ1AgLyBNUVRUIC8gV2ViUlRDKSAtLS0KICAgICMgRXhwb3NlZCBhcyBjb21tb24vcGx1Z2luLzxwbHVnaW5faWQ+L2hlbGxvLCBlLmcuCiAgICAjICAgY3VybCAtWCBQT1NUIGh0dHA6Ly88cm9ib3Q+L2NvbW1vbi9wbHVnaW4vPHBsdWdpbl9pZD4vaGVsbG8gXAogICAgIyAgICAgICAgLUggJ0NvbnRlbnQtVHlwZTogYXBwbGljYXRpb24vanNvbicgLWQgJ3sibmFtZSI6ICJraW0ifScKICAgICMgUmVzdHJpY3QgdHJhbnNwb3J0cyB3aXRoIGV4cGxpY2l0X3JvdXRlcz1bImFwaSJdIChSRVNUIG9ubHkpLCBldGMuCiAgICAjIFJhaXNlIFBsdWdpblJvdXRlRXJyb3IoNDAzLCAibXNnIikgdG8gc2V0IHRoZSByZXNwb25zZSBzdGF0dXMuCgogICAgQHBsdWdpbi5yb3V0ZXIub24oIi9oZWxsbyIpCiAgICBkZWYgaGVsbG8ocGF5bG9hZDogZGljdFtzdHIsIEFueV0gfCBOb25lID0gTm9uZSwgbWV0YTogZGljdFtzdHIsIEFueV0gfCBOb25lID0gTm9uZSk6CiAgICAgICAgIiIibWV0YSA9IHsidHJhbnNwb3J0IjogImFwaSJ8InNvY2tldCJ8InRjcCJ8Im1xdHQifCJ3ZWJydGMiLCAicHJpbmNpcGFsIjogZGljdCB8IE5vbmV9LiIiIgogICAgICAgIG5hbWUgPSAocGF5bG9hZCBvciB7fSkuZ2V0KCJuYW1lIiwgInRoZXJlIikKICAgICAgICByZXR1cm4geyJtc2ciOiBmImhpIHtuYW1lfSIsICJ2aWEiOiAobWV0YSBvciB7fSkuZ2V0KCJ0cmFuc3BvcnQiKX0KCgpkZWYgbW92ZV9qX2V4YW1wbGUoKToKICAgICIiIgogICAgRXhhbXBsZTogdXNlIG90aGVyIHJvYm90IFNES3MgZnJvbSB0aGUgc2FtZSBiYWNrZW5kLgoKICAgIFRoaXMgZnVuY3Rpb24gaXMgbm90IGNhbGxlZCBhdXRvbWF0aWNhbGx5LiBBZGQgc2FmZXR5IGNoZWNrcyBhbmQgY2FsbCBpdAogICAgZnJvbSB5b3VyIG93biBoYW5kbGVyIHdoZW4gdGhlIHJvYm90IGlzIHJlYWR5LgogICAgIiIiCiAgICByZXR1cm4gbWFuaXB1bGF0ZS5tb3ZlLmNhbGxfbW92ZV9qKAogICAgICAgIHJvYm90X21vZGVsPSJDNTAwOTIwIiwKICAgICAgICB0YXJnZXQ9ewogICAgICAgICAgICAidGFyX3ZhbHVlcyI6IFswLCAwLCAwLCAwLCAwLCAwLCAwXSwKICAgICAgICAgICAgInRhcl9mcmFtZSI6IC0xLAogICAgICAgICAgICAidGFyX3VuaXQiOiAwLAogICAgICAgIH0sCiAgICApCgoKYXN5bmMgZGVmIG1haW4oKToKICAgIHJvYm90X2hvc3QgPSBvcy5nZXRlbnYoIk1VU0NBVF9ST0JPVF9IT1NUIikKICAgIHJvYm90X3Rva2VuID0gb3MuZ2V0ZW52KCJNVVNDQVRfUk9CT1RfVE9LRU4iLCAiIikgICMgZW1wdHkgaXMgZmluZSB3aGVuIHRoZSBsb2dpbiBwb2xpY3kgaXMgb2ZmCgogICAgaWYgcm9ib3RfaG9zdDoKICAgICAgICAjIFJlbW90ZSBkZXY6IGNvbm5lY3QgdG8gdGhlIHJvYm90IGJlZm9yZSByZWdpc3RlcmluZyBhbnkgaGFuZGxlcnMuCiAgICAgICAgIyBjb25uZWN0KCkgY2xvc2VzIGFuZCByZW9wZW5zIHRoZSBaZW5vaCBzZXNzaW9uLCBzbyBoYW5kbGVycyByZWdpc3RlcmVkCiAgICAgICAgIyBiZWZvcmUgdGhpcyBjYWxsIHdvdWxkIGJlIGxvc3QuCiAgICAgICAgb3B0cyA9IENvbm5lY3RPcHRpb25zKCkKICAgICAgICBvcHRzLnRva2VuID0gcm9ib3RfdG9rZW4KICAgICAgICBvcHRzLmhvc3QgPSByb2JvdF9ob3N0CiAgICAgICAgbWFuaXB1bGF0ZS5jb25uZWN0KG9wdHMpCgogICAgcmVnaXN0ZXJfaGFuZGxlcnMoKQoKICAgIHBsdWdpbi5wdWJsaXNoKCJzdGF0ZSIsIHsicmVhZHkiOiBUcnVlLCAicGx1Z2luIjogUExVR0lOX05BTUV9KSAgICAgICAjIC0+IHBsdWdpbiBVSQogICAgcGx1Z2luLnJvdXRlci5lbWl0KCIvc3RhdGUiLCB7InJlYWR5IjogVHJ1ZSwgInBsdWdpbiI6IFBMVUdJTl9OQU1FfSkgICMgLT4gZXh0ZXJuYWwgc3Vic2NyaWJlcnMgb2YgY29tbW9uL3BsdWdpbi88cGx1Z2luX2lkPi9zdGF0ZQogICAgcHJpbnQoZiJbe1BMVUdJTl9OQU1FfV0gYmFja2VuZCByZWFkeSIpCgogICAgdHJ5OgogICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgIGF3YWl0IGFzeW5jaW8uc2xlZXAoMSkKICAgIGV4Y2VwdCAoS2V5Ym9hcmRJbnRlcnJ1cHQsIGFzeW5jaW8uQ2FuY2VsbGVkRXJyb3IpOgogICAgICAgIHBhc3MKICAgIGZpbmFsbHk6CiAgICAgICAgaWYgcm9ib3RfaG9zdDoKICAgICAgICAgICAgYXdhaXQgbWFuaXB1bGF0ZS5kaXNjb25uZWN0KCkKICAgICAgICBwcmludChmIlt7UExVR0lOX05BTUV9XSBzdG9wcGVkIikKCgppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOgogICAgdHJ5OgogICAgICAgIGFzeW5jaW8ucnVuKG1haW4oKSkKICAgIGV4Y2VwdCBLZXlib2FyZEludGVycnVwdDoKICAgICAgICBwYXNzCg==","common/requirements.txt":"cmFpbmJvdy1yYi1zZGs9PTAuMTAuMgpyYWluYm93LXJiLWZsYXQtYnVmZmVycz09MC4xMC4yCnJhaW5ib3ctcmItemVub2g9PTAuMTAuMgpyZXF1ZXN0cz09Mi4zNC4yCg==","common/tsconfig.json":"ewogICJjb21waWxlck9wdGlvbnMiOiB7CiAgICAidGFyZ2V0IjogIkVTTmV4dCIsCiAgICAibW9kdWxlIjogIkVTTmV4dCIsCiAgICAibW9kdWxlUmVzb2x1dGlvbiI6ICJidW5kbGVyIiwKICAgICJqc3giOiAicmVhY3QtanN4IiwKICAgICJzdHJpY3QiOiB0cnVlLAogICAgInNraXBMaWJDaGVjayI6IHRydWUsCiAgICAibm9FbWl0IjogdHJ1ZSwKICAgICJsaWIiOiBbIkRPTSIsICJET00uSXRlcmFibGUiLCAiRVNOZXh0Il0KICB9LAogICJpbmNsdWRlIjogWyJ1aSJdCn0K","common/ui/content.tsx":"aW1wb3J0IHsgdXNlTWVtbywgdXNlU3RhdGUgfSBmcm9tICJyZWFjdCI7CmltcG9ydCB7CiAgUkJDaGVja0JveCwKICBSQkxhYmVsQnV0dG9uLAogIFJCUmFkaW9Cb3gsCiAgUkJTZWxlY3RCb3gsCiAgUkJTbGlkZXIsCiAgUkJTd2l0Y2gsCiAgUkJUZXh0QXJlYSwKICBSQlRleHRGaWVsZCwKICBSQlRleHRJbnB1dCwKICBPcHRpb24KfSBmcm9tICJAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWkvcmVhY3QiOwppbXBvcnQgeyB1c2VSYiB9IGZyb20gIkByYWluYm93LXJvYm90aWNzL3BsdWdpbi11aS9zZGsiOwoKdHlwZSBSdW5Nb2RlID0gImluc3BlY3QiIHwgImFzc2lzdCIgfCAiYXV0byI7Cgpjb25zdCBNT0RFX09QVElPTlM6IEFycmF5PHsgbGFiZWw6IHN0cmluZzsgdmFsdWU6IFJ1bk1vZGUgfT4gPSBbCiAgeyBsYWJlbDogIkluc3BlY3QiLCB2YWx1ZTogImluc3BlY3QiIH0sCiAgeyBsYWJlbDogIkFzc2lzdCIsIHZhbHVlOiAiYXNzaXN0IiB9LAogIHsgbGFiZWw6ICJBdXRvIiwgdmFsdWU6ICJhdXRvIiB9LApdOwoKY29uc3QgVEFTS19PUFRJT05TID0gWwogIHsgbGFiZWw6ICJQdWJsaXNoIHN0YXR1cyIsIHZhbHVlOiAicHVibGlzaCIgfSwKICB7IGxhYmVsOiAiUnVuIGdyaXAgYWN0aW9uIiwgdmFsdWU6ICJncmlwIiB9LAogIHsgbGFiZWw6ICJTYXZlIHNuYXBzaG90IiwgdmFsdWU6ICJzbmFwc2hvdCIgfSwKXTsKCi8vIEV4cG9ydCB5b3VyIFVJIGFzIHRoZSBkZWZhdWx0LiBUaGUgaG9zdCBtb3VudHMgaXQgKGRldjogd2l0aCBITVIpLgpleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBBcHAoKSB7CiAgY29uc3QgcmIgPSB1c2VSYigpOwogIGNvbnN0IFt0YXJnZXROYW1lLCBzZXRUYXJnZXROYW1lXSA9IHVzZVN0YXRlKCJkZW1vX3RhcmdldCIpOwogIGNvbnN0IFtncmlwVHlwZSwgc2V0R3JpcFR5cGVdID0gdXNlU3RhdGU8c3RyaW5nPigpOwogIGNvbnN0IFtncmlwV2lkdGgsIHNldEdyaXBXaWR0aF0gPSB1c2VTdGF0ZSgyNCk7CiAgY29uc3QgW3NwZWVkLCBzZXRTcGVlZF0gPSB1c2VTdGF0ZSg0NSk7CiAgY29uc3QgW21vZGUsIHNldE1vZGVdID0gdXNlU3RhdGU8UnVuTW9kZT4oImFzc2lzdCIpOwogIGNvbnN0IFtlbmFibGVkLCBzZXRFbmFibGVkXSA9IHVzZVN0YXRlKHRydWUpOwogIGNvbnN0IFt0YXNrcywgc2V0VGFza3NdID0gdXNlU3RhdGU8QXJyYXk8c3RyaW5nPj4oWyJwdWJsaXNoIiwgImdyaXAiXSk7CiAgY29uc3QgW21lbW8sIHNldE1lbW9dID0gdXNlU3RhdGUoIlVzZSB0aGlzIGFyZWEgZm9yIG9wZXJhdG9yIG5vdGVzLiIpOwoKICBjb25zdCBwYXlsb2FkID0gdXNlTWVtbygKICAgICgpID0+ICh7CiAgICAgIHRhcmdldE5hbWUsCiAgICAgIGdyaXBXaWR0aCwKICAgICAgc3BlZWQsCiAgICAgIG1vZGUsCiAgICAgIGVuYWJsZWQsCiAgICAgIHRhc2tzLAogICAgICBtZW1vLAogICAgfSksCiAgICBbdGFyZ2V0TmFtZSwgZ3JpcFdpZHRoLCBzcGVlZCwgbW9kZSwgZW5hYmxlZCwgdGFza3MsIG1lbW9dLAogICk7CgogIGNvbnN0IHNob3dSZXF1ZXN0RXJyb3IgPSAoZXJyb3I6IHVua25vd24pID0+IHsKICAgIGNvbnN0IG1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6ICJSZXF1ZXN0IGZhaWxlZCI7CiAgICByYi50b2FzdCh7IHR5cGU6ICJkYW5nZXIiLCBtZXNzYWdlIH0pOwogIH07CgogIGNvbnN0IHJ1bkFjdGlvbiA9IGFzeW5jICgpID0+IHsKICAgIHRyeSB7CiAgICAgIGF3YWl0IHJiLmFjdGlvbigiZ3JpcCIsIHBheWxvYWQpOwogICAgICByYi50b2FzdCh7IHR5cGU6ICJzdWNjZXNzIiwgbWVzc2FnZTogYFNlbnQgJHt0YXJnZXROYW1lfWAgfSk7CiAgICB9IGNhdGNoIChlcnJvcikgewogICAgICBzaG93UmVxdWVzdEVycm9yKGVycm9yKTsKICAgIH0KICB9OwoKICBjb25zdCBwdWJsaXNoUHJldmlldyA9IGFzeW5jICgpID0+IHsKICAgIHRyeSB7CiAgICAgIGNvbnN0IGlzQ29uZmlybSA9IGF3YWl0IHJiLmNvbmZpcm0oewogICAgICAgIG1lc3NhZ2U6ICJBcmUgeW91IHN1cmUgcHVibGlzaD8iLAogICAgICAgIGJ1dHRvblRleHQ6IHsgeWVzOiAiY29uZmlybSIsIG5vOiAiY2FuY2VsIiB9LAogICAgICB9KTsKCiAgICAgIGlmIChpc0NvbmZpcm0pIHsKICAgICAgICBhd2FpdCByYi5wdWIoImV2ZW50IiwgcGF5bG9hZCk7CiAgICAgIH0KICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICAgIHNob3dSZXF1ZXN0RXJyb3IoZXJyb3IpOwogICAgfQogIH07CgogIHJldHVybiAoCiAgICA8ZGl2IGNsYXNzTmFtZT0ibWF4LWgtWzcwdmhdIHctWzQyMHB4XSBwLTQgbWF4LXctZnVsbCBvdmVyZmxvdy15LWF1dG8gYmctYmctZWxldmF0ZWQgdGV4dC1mZy1kZWZhdWx0Ij4KICAgICAgPGRpdiBjbGFzc05hbWU9ImZsZXggZmxleC1jb2wgZ2FwLTUiPgogICAgICAgIDxoZWFkZXI+CiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0iZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1iZXR3ZWVuIGdhcC0xMiI+CiAgICAgICAgICAgIDxkaXY+CiAgICAgICAgICAgICAgPGgyIGNsYXNzTmFtZT0idHlwby1oZWFkaW5nLXhzLXNlbWlib2xkIj5EZW1vIENvbnRyb2w8L2gyPgogICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0idHlwby1ib2R5LXhzMi1ub3JtYWwgdGV4dC1mZy1zdWJ0bGUiPgogICAgICAgICAgICAgICAgSW5wdXQgcGF0dGVybnMgZm9yIE11c2NhdCBwbHVnaW4gVUlzCiAgICAgICAgICAgICAgPC9wPgogICAgICAgICAgICA8L2Rpdj4KICAgICAgICAgICAgPFJCU3dpdGNoCiAgICAgICAgICAgICAgY2hlY2tlZD17ZW5hYmxlZH0KICAgICAgICAgICAgICBvbkNoZWNrZWRDaGFuZ2U9eyhuZXh0OiBib29sZWFuKSA9PiB7CiAgICAgICAgICAgICAgICBzZXRFbmFibGVkKG5leHQpOwogICAgICAgICAgICAgICAgcmIudG9hc3Qoe21lc3NhZ2U6IG5leHQgPyAiUGx1Z2luIGVuYWJsZWQiIDogIlBsdWdpbiBwYXVzZWQifSk7CiAgICAgICAgICAgICAgfX0KICAgICAgICAgICAgLz4KICAgICAgICAgIDwvZGl2PgogICAgICAgIDwvaGVhZGVyPgoKICAgICAgICA8c2VjdGlvbiBjbGFzc05hbWU9ImZsZXggZmxleC1jb2wgZ2FwLTQiPgogICAgICAgICAgPFJCVGV4dEZpZWxkCiAgICAgICAgICAgIGxhYmVsPSJUYXJnZXQgbmFtZSIKICAgICAgICAgICAgcmVxdWlyZWQKICAgICAgICAgICAgaGVscGVyVGV4dD0iVXNlZCBhcyB0aGUgYmFja2VuZCBhY3Rpb24gdGFyZ2V0LiIKICAgICAgICAgID4KICAgICAgICAgICAgPFJCVGV4dElucHV0CiAgICAgICAgICAgICAgbmFtZT0idGFyZ2V0TmFtZSIKICAgICAgICAgICAgICB2YWx1ZT17dGFyZ2V0TmFtZX0KICAgICAgICAgICAgICBwbGFjZWhvbGRlcj0idGFyZ2V0IGlkIgogICAgICAgICAgICAgIGhhbmRsZUNoYW5nZT17KHZhbHVlKSA9PiBzZXRUYXJnZXROYW1lKFN0cmluZyh2YWx1ZSkpfQogICAgICAgICAgICAvPgogICAgICAgICAgPC9SQlRleHRGaWVsZD4KCiAgICAgICAgICA8UkJUZXh0RmllbGQgbGFiZWw9IlNlbGVjdCBHcmlwIj4KICAgICAgICAgICAgPFJCU2VsZWN0Qm94ICBjbGFzc05hbWU9InctZnVsbCIgdmFsdWU9e2dyaXBUeXBlfSBoYW5kbGVDaGFuZ2U9e3NldEdyaXBUeXBlfT4KICAgICAgICAgICAgICA8T3B0aW9uIHZhbHVlPSJBIj5BIEdyaXA8L09wdGlvbj4KICAgICAgICAgICAgICA8T3B0aW9uIHZhbHVlPSJCIj5CIEdyaXA8L09wdGlvbj4KICAgICAgICAgICAgPC9SQlNlbGVjdEJveD4KICAgICAgICAgIDwvUkJUZXh0RmllbGQ+CgogICAgICAgICAgPGRpdiBjbGFzc05hbWU9ImZsZXggZ2FwLTQiPgogICAgICAgICAgICA8UkJUZXh0RmllbGQgY2xhc3NOYW1lPSJmbGV4LTEiIGxhYmVsPSJHcmlwIHdpZHRoIiBoZWxwZXJUZXh0PSIwLTEwMCBtbSI+CiAgICAgICAgICAgICAgPFJCVGV4dElucHV0CiAgICAgICAgICAgICAgICBjbGFzc05hbWU9InctZnVsbCIKICAgICAgICAgICAgICAgIG5hbWU9ImdyaXBXaWR0aCIKICAgICAgICAgICAgICAgIHR5cGU9Im51bWJlciIKICAgICAgICAgICAgICAgIHZhbHVlPXtncmlwV2lkdGh9CiAgICAgICAgICAgICAgICB2YWxpZGF0ZT17KHZhbHVlOiBudW1iZXIpID0+CiAgICAgICAgICAgICAgICAgIE1hdGgubWF4KDAsIE1hdGgubWluKDEwMCwgTnVtYmVyKHZhbHVlKSB8fCAwKSkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGhhbmRsZUNoYW5nZT17KHZhbHVlKSA9PiBzZXRHcmlwV2lkdGgoTnVtYmVyKHZhbHVlKSB8fCAwKX0KICAgICAgICAgICAgICAvPgogICAgICAgICAgICA8L1JCVGV4dEZpZWxkPgoKICAgICAgICAgICAgPFJCVGV4dEZpZWxkIGNsYXNzTmFtZT0iZmxleC0xIiBsYWJlbD0iU3BlZWQiIGhlbHBlclRleHQ9e2Ake3NwZWVkfSVgfT4KICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0iZmxleCBpdGVtcy1jZW50ZXIgcHgtMiI+CiAgICAgICAgICAgICAgICA8UkJTbGlkZXIKICAgICAgICAgICAgICAgICAgdmFsdWU9e1tzcGVlZF19CiAgICAgICAgICAgICAgICAgIG1pbj17MH0KICAgICAgICAgICAgICAgICAgbWF4PXsxMDB9CiAgICAgICAgICAgICAgICAgIHN0ZXA9ezV9CiAgICAgICAgICAgICAgICAgIG9uVmFsdWVDaGFuZ2U9eyh2YWx1ZXM6IG51bWJlcltdKSA9PgogICAgICAgICAgICAgICAgICAgIHNldFNwZWVkKHZhbHVlc1swXSA/PyAwKQogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvPgogICAgICAgICAgICAgIDwvZGl2PgogICAgICAgICAgICA8L1JCVGV4dEZpZWxkPgogICAgICAgICAgPC9kaXY+CiAgICAgICAgPC9zZWN0aW9uPgoKICAgICAgICA8c2VjdGlvbiBjbGFzc05hbWU9Im1iLTQiPgogICAgICAgICAgPFJCVGV4dEZpZWxkIGxhYmVsPSJSdW4gbW9kZSI+CiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSJmbGV4IGp1c3RpZnktYmV0d2VlbiBib3JkZXItMSBib3JkZXItYm9yZGVyLXN1YnRsZSByb3VuZGVkLXNtIHAtMiI+CiAgICAgICAgICAgIHtNT0RFX09QVElPTlMubWFwKChpdGVtKSA9PiAoCiAgICAgICAgICAgICAgPFJCUmFkaW9Cb3gKICAgICAgICAgICAgICAgIGtleT17aXRlbS52YWx1ZX0KICAgICAgICAgICAgICAgIG5hbWU9Im1vZGUiCiAgICAgICAgICAgICAgICBjaGVja1ZhbHVlPXtpdGVtLnZhbHVlfQogICAgICAgICAgICAgICAgdmFsdWU9e21vZGV9CiAgICAgICAgICAgICAgICBoYW5kbGVDaGFuZ2U9eyh2YWx1ZSkgPT4gc2V0TW9kZSh2YWx1ZSBhcyBSdW5Nb2RlKX0KICAgICAgICAgICAgICA+CiAgICAgICAgICAgICAgICB7aXRlbS5sYWJlbH0KICAgICAgICAgICAgICA8L1JCUmFkaW9Cb3g+CiAgICAgICAgICAgICkpfQogICAgICAgICAgPC9kaXY+CiAgICAgICAgICA8L1JCVGV4dEZpZWxkPgogICAgICAgIDwvc2VjdGlvbj4KCiAgICAgICAgPHNlY3Rpb24gY2xhc3NOYW1lPSJtYi00Ij4KICAgICAgICAgIDxSQlRleHRGaWVsZCBsYWJlbD0iVGFza3MiPgogICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0iZmxleCBqdXN0aWZ5LWJldHdlZW4gYm9yZGVyLTEgYm9yZGVyLWJvcmRlci1zdWJ0bGUgcm91bmRlZC1zbSBwLTIiPgogICAgICAgICAgICAgIHtUQVNLX09QVElPTlMubWFwKChpdGVtKSA9PiAoCiAgICAgICAgICAgICAgICA8UkJDaGVja0JveAogICAgICAgICAgICAgICAgICBrZXk9e2l0ZW0udmFsdWV9CiAgICAgICAgICAgICAgICAgIG5hbWU9InRhc2tzIgogICAgICAgICAgICAgICAgICBjaGVja1ZhbHVlPXtpdGVtLnZhbHVlfQogICAgICAgICAgICAgICAgICB2YWx1ZT17dGFza3N9CiAgICAgICAgICAgICAgICAgIGhhbmRsZUNoYW5nZT17KHZhbHVlKSA9PgogICAgICAgICAgICAgICAgICAgIHNldFRhc2tzKEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWUubWFwKFN0cmluZykgOiBbXSkKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgPgogICAgICAgICAgICAgICAgICB7aXRlbS5sYWJlbH0KICAgICAgICAgICAgICAgIDwvUkJDaGVja0JveD4KICAgICAgICAgICAgICApKX0KICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgICA8L1JCVGV4dEZpZWxkPgogICAgICAgICAgCiAgICAgICAgPC9zZWN0aW9uPgoKICAgICAgICA8UkJUZXh0RmllbGQgbGFiZWw9Ik1lbW8iPgogICAgICAgICAgPFJCVGV4dEFyZWEKICAgICAgICAgICAgbmFtZT0ibWVtbyIKICAgICAgICAgICAgdmFsdWU9e21lbW99CiAgICAgICAgICAgIG1heExlbmd0aD17MTIwfQogICAgICAgICAgICByb3dzPXs0fQogICAgICAgICAgICBoYW5kbGVDaGFuZ2U9e3NldE1lbW99CiAgICAgICAgICAvPgogICAgICAgIDwvUkJUZXh0RmllbGQ+CgogICAgICAgIDxmb290ZXIgY2xhc3NOYW1lPSJncmlkIGdyaWQtY29scy0yIGdhcC04IHB0LTQiPgogICAgICAgICAgPFJCTGFiZWxCdXR0b24gdmFyaWFudD0ib3V0bGluZWQiIG9uQ2xpY2s9e3B1Ymxpc2hQcmV2aWV3fT4KICAgICAgICAgICAgUHVibGlzaAogICAgICAgICAgPC9SQkxhYmVsQnV0dG9uPgogICAgICAgICAgPFJCTGFiZWxCdXR0b24gb25DbGljaz17cnVuQWN0aW9ufSBkaXNhYmxlZD17IWVuYWJsZWR9PgogICAgICAgICAgICBSdW4gQWN0aW9uCiAgICAgICAgICA8L1JCTGFiZWxCdXR0b24+CiAgICAgICAgPC9mb290ZXI+CiAgICAgIDwvZGl2PgogICAgPC9kaXY+CiAgKTsKfQo=","common/ui/style.css":"QGxheWVyIHRoZW1lLCB1dGlsaXRpZXM7CgpAaW1wb3J0ICJ0YWlsd2luZGNzcy90aGVtZS5jc3MiIGxheWVyKHRoZW1lKTsKQGltcG9ydCAidGFpbHdpbmRjc3MvdXRpbGl0aWVzLmNzcyIgbGF5ZXIodXRpbGl0aWVzKTsKCkBzb3VyY2UgIi4vKiovKi57dHMsdHN4fSI7Cg==","common/vite.config.ts":"aW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAidml0ZSI7CmltcG9ydCB0YWlsd2luZGNzcyBmcm9tICJAdGFpbHdpbmRjc3Mvdml0ZSI7CmltcG9ydCB7IG11c2NhdCB9IGZyb20gIkByYWluYm93LXJvYm90aWNzL211c2NhdC1wbHVnaW4ta2l0L3ZpdGUiOwoKLy8gVGhlIG11c2NhdCgpIHByZXNldCB3aXJlcyByZWFjdC1yZWZyZXNoLCB1aS8gZW50cnkgZGlzY292ZXJ5LCBhbmQgbWFya3MgdGhlCi8vIGhvc3QtcHJvdmlkZWQgcnVudGltZSAocGx1Z2luLXVpLCByZWFjdCkgYXMgZXh0ZXJuYWwuIEFkZCB5b3VyIG93biBwbHVnaW5zIG9yCi8vIG92ZXJyaWRlcyBoZXJlIGFzIG5lZWRlZC4KZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHsKICBwbHVnaW5zOiBbdGFpbHdpbmRjc3MoKSwgbXVzY2F0KCldLAp9KTsK","cpp/cpp/CMakeLists.txt":"Y21ha2VfbWluaW11bV9yZXF1aXJlZChWRVJTSU9OIDMuMTYpCnByb2plY3QoX19QTFVHSU5fU0xVR19fIENYWCkKCnNldChDTUFLRV9DWFhfU1RBTkRBUkQgMjApCnNldChDTUFLRV9DWFhfU1RBTkRBUkRfUkVRVUlSRUQgT04pCgojIFJhaW5ib3cgUm9ib3RpY3MgQysrIFNESyDigJQgcHJvdmlkZWQgYnkgdGhlIGFwdCBwYWNrYWdlIHJhaW5ib3ctcmItc2RrLWRldgojIChwcmUtaW5zdGFsbGVkIGluIHRoZSBtdXNjYXQtcGsgZGV2IGNvbnRhaW5lcikuIFRoZSB2ZXJzaW9uIGhlcmUgaXMgdGhlIG9uZSB0aGUKIyBkZXYgY29udGFpbmVyIGluc3RhbGxzOyBjaGFuZ2UgaXQgd2l0aCBgbXVzY2F0LXBrIHNkayB1cGRhdGUgPHZlcnNpb24+YC4KZmluZF9wYWNrYWdlKHJiX3NkayAwLjEwLjIgRVhBQ1QgUkVRVUlSRUQpCgojIFRoZSBleGVjdXRhYmxlIG5hbWUgbXVzdCBtYXRjaCBydW50aW1lLmVudHJ5IGluIG1hbmlmZXN0Lmpzb24uCmFkZF9leGVjdXRhYmxlKF9fUExVR0lOX1NMVUdfXyBtYWluLmNwcCkKdGFyZ2V0X2xpbmtfbGlicmFyaWVzKF9fUExVR0lOX1NMVUdfXyBQUklWQVRFIHJiX3Nkazo6cmJfc2RrKQo=","cpp/cpp/main.cpp":"Ly8gX19QTFVHSU5fTkFNRV9fIOKAlCBDKysgcGx1Z2luIGJhY2sgZW5kLgovLwovLyBUaGUgUmFpbmJvdyBSb2JvdGljcyBDKysgU0RLIChhcHQ6IHJhaW5ib3ctcmItc2RrLWRldikgaXMgaW5zdGFsbGVkIGluIHRoZQovLyBkZXYgY29udGFpbmVyIGFuZCBsaW5rZWQgdmlhIENNYWtlIChyYl9zZGs6OnJiX3NkaykuIEhlYWRlcnMgbGl2ZSB1bmRlcgovLyA8cmFpbmJvdy9yYl9zZGsvLi4uPjoKLy8gICAtIHBsdWdpbi9yYl9wbHVnaW4uaHBwICAgICAgICAgICAgICAgcmJfcGx1Z2luOjpSQlBsdWdpbkNhbGwg4oCUIHBsdWdpbiBVSSA8LT4gYmFja2VuZAovLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc2VydmUvc3Vic2NyaWJlL3B1Ymxpc2gpIGFuZCBleHRlcm5hbCBlbmRwb2ludHMgKHJvdXRlcikKLy8gICAtIG1hbmlwdWxhdGUvcmJfbWFuaXB1bGF0ZV9zZGsuaHBwICAgUkJNYW5pcHVsYXRlU0RLIOKAlCBjb250cm9sIHRoZSByb2JvdAovLyAgIC0gcHJvZ3JhbS9wbHVnaW5fcHJvZ3JhbV9jb250ZXh0LmhwcCByYl9wbHVnaW46OlBsdWdpblByb2dyYW1Db250ZXh0IOKAlAovLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9ncmFtLnBhbmVsIGNvbW1hbmRzIChkb25lL3BhdXNlL3N0b3AsCi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb2dyYW0gdmFyaWFibGVzKQoKI2luY2x1ZGUgPHJhaW5ib3cvcmJfc2RrL21hbmlwdWxhdGUvcmJfbWFuaXB1bGF0ZV9zZGsuaHBwPgojaW5jbHVkZSA8cmFpbmJvdy9yYl9zZGsvcGx1Z2luL3JiX3BsdWdpbi5ocHA+CgojaW5jbHVkZSA8bmxvaG1hbm4vanNvbi5ocHA+CgojaW5jbHVkZSA8Y2hyb25vPgojaW5jbHVkZSA8Y3N0ZGxpYj4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8dGhyZWFkPgoKdXNpbmcgbmxvaG1hbm46Ompzb247CnVzaW5nIHJiX3BsdWdpbjo6UkJQbHVnaW5DYWxsOwoKaW50IG1haW4oKSB7CiAgY29uc3Qgc3RkOjpzdHJpbmcgbmFtZSA9ICJfX1BMVUdJTl9OQU1FX18iOwoKICAvLyBSZW1vdGUgZGV2OiBjb25uZWN0IGJlZm9yZSByZWdpc3RlcmluZyBoYW5kbGVycyAoY29ubmVjdCgpIHJlb3BlbnMgdGhlIHNlc3Npb24pLgogIFJCTWFuaXB1bGF0ZVNESyBtYW5pcHVsYXRlOwogIGNvbnN0IGNoYXIqIGhvc3QgPSBzdGQ6OmdldGVudigiTVVTQ0FUX1JPQk9UX0hPU1QiKTsKICBjb25zdCBjaGFyKiB0b2tlbiA9IHN0ZDo6Z2V0ZW52KCJNVVNDQVRfUk9CT1RfVE9LRU4iKTsgIC8vIG9wdGlvbmFsOiBuZWVkZWQgb25seSB3aGVuIHRoZSBsb2dpbiBwb2xpY3kgaXMgb24KICBpZiAoaG9zdCkgbWFuaXB1bGF0ZS5jb25uZWN0KHsudG9rZW4gPSB0b2tlbiA/IHRva2VuIDogIiIsIC5ob3N0ID0gaG9zdH0pOwoKICAvLyBwbHVnaW4gaWQgY29tZXMgZnJvbSBSQl9QTFVHSU5fSUQuCiAgYXV0byBwbHVnaW4gPSBSQlBsdWdpbkNhbGw6OmdldF9pbnN0YW5jZShSQlBsdWdpbkNhbGw6OnJlc29sdmVfcGx1Z2luX2lkKHN0ZDo6bnVsbG9wdCkpOwoKICAvLyAtLS0gUGx1Z2luIFVJIDwtPiBiYWNrZW5kIChub3QgcmVhY2hhYmxlIGZyb20gb3V0c2lkZSBNdXNjYXQpIC0tLQoKICAvLyBVSTogYXdhaXQgcmIuYWN0aW9uKCJncmlwIiwgeyB3aWR0aCB9KQogIHBsdWdpbi0+c2VydmUoImdyaXAiLCBbJl0oY29uc3QganNvbiYgcGF5bG9hZCkgewogICAgY29uc3QgaW50IHdpZHRoID0gcGF5bG9hZC5pc19vYmplY3QoKSA/IHBheWxvYWQudmFsdWUoIndpZHRoIiwgMjApIDogMjA7CiAgICBzdGQ6OmNvdXQgPDwgIlsiIDw8IG5hbWUgPDwgIl0gZ3JpcCByZXF1ZXN0ZWQ6IHdpZHRoPSIgPDwgd2lkdGggPDwgc3RkOjplbmRsOwogICAgcGx1Z2luLT5wdWJsaXNoKCJzdGF0ZSIsIHt7InJlYWR5IiwgdHJ1ZX0sIHsibGFzdF9ncmlwX3dpZHRoIiwgd2lkdGh9fSk7ICAvLyAtPiByYi5zdWIoInN0YXRlIikKICAgIHJldHVybiBqc29ue3sib2siLCB0cnVlfSwgeyJ3aWR0aCIsIHdpZHRofX07CiAgfSk7CgogIC8vIFVJOiByYi5wdWIoImV2ZW50IiwgLi4uKQogIGF1dG8gZXZlbnRfc3ViID0gcGx1Z2luLT5zdWJzY3JpYmUoImV2ZW50IiwgWyZdKGNvbnN0IHN0ZDo6c3RyaW5nJiwgY29uc3QganNvbiYgcGF5bG9hZCkgewogICAgc3RkOjpjb3V0IDw8ICJbIiA8PCBuYW1lIDw8ICJdIGV2ZW50OiAiIDw8IHBheWxvYWQuZHVtcCgpIDw8IHN0ZDo6ZW5kbDsKICB9KTsKCiAgLy8gLS0tIEV4dGVybmFsIGVuZHBvaW50cyAoUkVTVCAvIFNvY2tldC5JTyAvIFRDUCAvIE1RVFQgLyBXZWJSVEMpIC0tLQogIC8vICAgY3VybCAtWCBQT1NUIGh0dHA6Ly88cm9ib3Q+L2NvbW1vbi9wbHVnaW4vPHBsdWdpbl9pZD4vaGVsbG8gLWQgJ3sibmFtZSI6ImtpbSJ9JwogIHBsdWdpbi0+cm91dGVyKCkub24oIi9oZWxsbyIsIFtdKGNvbnN0IGpzb24mIHBheWxvYWQsIGNvbnN0IGpzb24mIG1ldGEpIHsKICAgIGNvbnN0IHN0ZDo6c3RyaW5nIHdobyA9IHBheWxvYWQuaXNfb2JqZWN0KCkgPyBwYXlsb2FkLnZhbHVlKCJuYW1lIiwgc3RkOjpzdHJpbmcoInRoZXJlIikpIDogInRoZXJlIjsKICAgIHJldHVybiBqc29ue3sibXNnIiwgImhpICIgKyB3aG99LCB7InZpYSIsIG1ldGEudmFsdWUoInRyYW5zcG9ydCIsIHN0ZDo6c3RyaW5nKCkpfX07CiAgfSk7CgogIC8vIEV4YW1wbGU6IHJvYm90IGNvbnRyb2wgKG5vdCBjYWxsZWQgYXV0b21hdGljYWxseSDigJQgYWRkIHNhZmV0eSBjaGVja3MgZmlyc3QpLgogIC8vICAgSVBDOjpNb3ZlSW5wdXRfVGFyZ2V0VCB0OyB0LnRhcl92YWx1ZXMgPSB7MCwgMCwgMCwgMCwgMCwgMCwgMH07IHQudGFyX2ZyYW1lID0gLTE7IHQudGFyX3VuaXQgPSAwOwogIC8vICAgbWFuaXB1bGF0ZS5tb3ZlLmNhbGxfbW92ZV9qKCJDNTAwOTIwIiwgdCk7CgogIHBsdWdpbi0+cHVibGlzaCgic3RhdGUiLCB7eyJyZWFkeSIsIHRydWV9LCB7InBsdWdpbiIsIG5hbWV9fSk7CiAgc3RkOjpjb3V0IDw8ICJbIiA8PCBuYW1lIDw8ICJdIGJhY2tlbmQgcmVhZHkiIDw8IHN0ZDo6ZW5kbDsKCiAgLy8gS2VlcCB0aGUgcHJvY2VzcyBhbGl2ZS4KICB3aGlsZSAodHJ1ZSkgewogICAgc3RkOjp0aGlzX3RocmVhZDo6c2xlZXBfZm9yKHN0ZDo6Y2hyb25vOjpzZWNvbmRzKDEpKTsKICB9CiAgcmV0dXJuIDA7Cn0K","readme-cpp/README.md":"IyBfX1BMVUdJTl9OQU1FX18KCkEgTXVzY2F0IHBsdWdpbiBwcm9qZWN0LiBCdWlsZCwgZGV2ZWxvcCwgYW5kIHNoaXAgd2l0aCBgbXVzY2F0LXBrYCBDTEkuCgojIyBRdWljayBzdGFydAoKYGBgYmFzaAptdXNjYXQtcGsgZGV2ICAgICAgICAjIFVJIHByZXZpZXcgKyBiYWNrZW5kIHRvZ2V0aGVyCm11c2NhdC1wayBkZXY6dWkgICAgICMgVUkgcHJldmlldyBvbmx5Cm11c2NhdC1wayBkZXY6YmFjayAgICMgYmFja2VuZCBvbmx5IChDKysgcmVidWlsZCArIHJlc3RhcnQgaW4gRG9ja2VyKQptdXNjYXQtcGsgYnVpbGQgICAgICAjIGJ1aWxkICsgZGlzdHJpYnV0YWJsZSBaSVAKYGBgCgotLS0KCiMjIFByb2plY3Qgc3RydWN0dXJlCgpgYGAKX19QTFVHSU5fRElSX18vCuKUnOKUgCB1aS8K4pSCICAg4pSc4pSAIGNvbnRlbnQudHN4ICAgICAgIyBwbHVnaW4gVUkgZW50cnkgcG9pbnQK4pSCICAg4pSU4pSAIHN0eWxlLmNzcyAgICAgICAgIyBwbHVnaW4gc3R5bGVzIGF1dG8tbG9hZGVkIGJ5IG11c2NhdCgpCuKUnOKUgCBjcHAvCuKUgiAgIOKUnOKUgCBDTWFrZUxpc3RzLnR4dCAgICMgbGlua3MgcmJfc2RrOjpyYl9zZGsgKEMrKyBTREspCuKUgiAgIOKUlOKUgCBtYWluLmNwcCAgICAgICAgICMgQysrIGJhY2tlbmQgZW50cnkgcG9pbnQK4pSc4pSAIGFzc2V0cy8K4pSCICAg4pSU4pSAIGljb24uc3ZnICAgICAgICAgIyBpY29uIHJlZmVyZW5jZWQgZnJvbSBtYW5pZmVzdArilJzilIAgbWFuaWZlc3QuanNvbiAgICAgICAgIyBtZXRhZGF0YSwgY29udHJpYnV0aW9uIHBvaW50cywgcnVudGltZSBjb25maWcK4pSU4pSAIFJFQURNRS5tZCAgICAgICAgICAgICMgdGhpcyBmaWxlIChjb3BpZWQgdG8gZGlzdC8gb24gYnVpbGQpCmBgYAoKPiBST1MyIChyY2xjcHApIHBsdWdpbnMgaGF2ZSBgcm9zMl93cy9gIGluc3RlYWQgb2YgYGNwcC9gLgoKLS0tCgojIyBGcm9udGVuZCAoYHVpL2NvbnRlbnQudHN4YCkKCiMjIyBKYXZhU2NyaXB0IGRlcGVuZGVuY2llcwoKYG11c2NhdC1wayBidWlsZGAgcnVucyB0aGlzIHBsdWdpbiBwcm9qZWN0J3Mgb3duIFZpdGUgYnVpbGQuIFZpdGUgcmVzb2x2ZXMKaW1wb3J0cyBmcm9tIGluc3RhbGxlZCBgbm9kZV9tb2R1bGVzYDsgaXQgZG9lcyBub3QgY2FyZSB3aGV0aGVyIGEgcGFja2FnZSBpcwpsaXN0ZWQgdW5kZXIgYGRlcGVuZGVuY2llc2Agb3IgYGRldkRlcGVuZGVuY2llc2AsIGJ1dCB0aGUgcGFja2FnZSBtdXN0IGJlCmluc3RhbGxlZC4KCkRvIG5vdCBydW4gYSBwcm9kdWN0aW9uLW9ubHkgaW5zdGFsbCBzdWNoIGFzIGBucG0gaW5zdGFsbCAtLW9taXQ9ZGV2YCBiZWZvcmUKYnVpbGRpbmcgdGhlIHBsdWdpbiBVSSwgYmVjYXVzZSBidWlsZCB0b29scyBsaWtlIGB2aXRlYCwgYHR5cGVzY3JpcHRgLApgdGFpbHdpbmRjc3NgLCBgQHRhaWx3aW5kY3NzL3ZpdGVgLCBgc2Fzc2AsIG9yIGBsZXNzYCBhcmUgdXN1YWxseQpgZGV2RGVwZW5kZW5jaWVzYC4KClRoZSBzY2FmZm9sZCBrZWVwcyB0aGlzIHNwbGl0OgoKfCBwYWNrYWdlIGtpbmQgfCBleGFtcGxlcyB8IHdoeSB8CnwtLS18LS0tfC0tLXwKfCBgZGVwZW5kZW5jaWVzYCB8IGBAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWlgLCBVSSBsaWJyYXJpZXMgaW1wb3J0ZWQgYnkgcGx1Z2luIHNvdXJjZSB8IEF1dGhvci1mYWNpbmcgQVBJcyB1c2VkIGJ5IGB1aS8qLnRzeGAgfAp8IGBkZXZEZXBlbmRlbmNpZXNgIHwgYHZpdGVgLCBgdHlwZXNjcmlwdGAsIGB0YWlsd2luZGNzc2AsIGBAdGFpbHdpbmRjc3Mvdml0ZWAsIGBzYXNzYCwgYGxlc3NgIHwgQnVpbGQvZGV2IHRvb2xzIG5lZWRlZCBiZWZvcmUgYGRpc3QvKi5qc2AgaXMgcHJvZHVjZWQgfAoKVGhlIGJ1aWx0IHBsdWdpbiBaSVAgZG9lcyBub3QgaW5jbHVkZSBgcGFja2FnZS5qc29uYCBvciBgbm9kZV9tb2R1bGVzYC4gRm9yCnByb2R1Y3Rpb24sIE11c2NhdCBwcm92aWRlcyBgQHJhaW5ib3ctcm9ib3RpY3MvcGx1Z2luLXVpYCwgUmVhY3QsIGFuZCBSZWFjdERPTQp0aHJvdWdoIHRoZSBob3N0IGltcG9ydCBtYXA7IHBsdWdpbiBVSSBidWlsZCBvdXRwdXQgaW1wb3J0cyB0aG9zZSBhcyBob3N0CmV4dGVybmFscy4KCiMjIyBTdHlsZXMKCmBtdXNjYXQoKWAgYXV0b21hdGljYWxseSBsb2FkcyBgdWkvc3R5bGUue2NzcyxzY3NzLHNhc3MsbGVzc31gIChvcgpgdWkvc3R5bGVzLntjc3Msc2NzcyxzYXNzLGxlc3N9YCkgZm9yIGV2ZXJ5IFVJIGVudHJ5LCBwbHVzCmB1aS97ZW50cnl9Lntjc3Msc2NzcyxzYXNzLGxlc3N9YCBmb3IgYSBtYXRjaGluZyBlbnRyeS1zcGVjaWZpYyBzdHlsZXNoZWV0LiBZb3UKZG8gbm90IG5lZWQgdG8gaW1wb3J0IENTUyBmcm9tIGV2ZXJ5IGAudHN4YCBmaWxlLgoKVGhlIHNjYWZmb2xkIHVzZXMgVGFpbHdpbmQncyB0aGVtZS91dGlsaXRpZXMgbGF5ZXJzIG9ubHksIHNvIHBsdWdpbiB1dGlsaXRpZXMKYXJlIGdlbmVyYXRlZCBmcm9tIGZpbGVzIHVuZGVyIGB1aS9gIHdpdGhvdXQgYXBwbHlpbmcgVGFpbHdpbmQgcHJlZmxpZ2h0IHJlc2V0cwp0byB0aGUgaG9zdCBwYWdlLgoKQnVpbHQgQ1NTIHNlbGVjdG9ycyBhcmUgc2NvcGVkIHVuZGVyIHRoZSBjdXJyZW50IHBsdWdpbiBpZAooYFtkYXRhLW11c2NhdC1wbHVnaW4taWQ9Ii4uLiJdYCkuIENTUy1pbi1KUyBsaWJyYXJpZXMgc3VjaCBhcyBFbW90aW9uIHdvcmsKbm9ybWFsbHksIGJ1dCBnbG9iYWwgc3R5bGVzIHNob3VsZCBiZSBzY29wZWQgYnkgdGhlIGF1dGhvci4KCiMjIyMgVGFpbHdpbmQKClRoaXMgdGVtcGxhdGUgZW5hYmxlcyBUYWlsd2luZCBpbiBgdml0ZS5jb25maWcudHNgOgoKYGBgdHMKaW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAidml0ZSI7CmltcG9ydCB0YWlsd2luZGNzcyBmcm9tICJAdGFpbHdpbmRjc3Mvdml0ZSI7CmltcG9ydCB7IG11c2NhdCB9IGZyb20gIkByYWluYm93LXJvYm90aWNzL211c2NhdC1wbHVnaW4ta2l0L3ZpdGUiOwoKZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHsKICBwbHVnaW5zOiBbdGFpbHdpbmRjc3MoKSwgbXVzY2F0KCldLAp9KTsKYGBgCgpUaGUgZGVmYXVsdCBgdWkvc3R5bGUuY3NzYCB1c2VzIFRhaWx3aW5kIHRoZW1lL3V0aWxpdGllcyBvbmx5LCBub3QgcHJlZmxpZ2h0OgoKYGBgY3NzCkBsYXllciB0aGVtZSwgdXRpbGl0aWVzOwoKQGltcG9ydCAidGFpbHdpbmRjc3MvdGhlbWUuY3NzIiBsYXllcih0aGVtZSk7CkBpbXBvcnQgInRhaWx3aW5kY3NzL3V0aWxpdGllcy5jc3MiIGxheWVyKHV0aWxpdGllcyk7CgpAc291cmNlICIuLyoqLyoue3RzLHRzeH0iOwpgYGAKCiMjIyMgU0NTUywgU2FzcywgYW5kIExlc3MKCkluc3RhbGwgdGhlIHByZXByb2Nlc3NvciBwYWNrYWdlLCB0aGVuIGNyZWF0ZSBvbmUgb2YgdGhlIGF1dG8tbG9hZGVkIHN0eWxlIGZpbGVzLgoKYGBgYmFzaApucG0gaSAtRCBzYXNzCmBgYAoKYGBgc2NzcwovKiB1aS9zdHlsZS5zY3NzICovCiRhY2NlbnQ6ICMzYjgyZjY7CgoucGFuZWwgewogIGJvcmRlcjogMXB4IHNvbGlkIGNvbG9yLW1peChpbiBzcmdiLCAkYWNjZW50IDQwJSwgdHJhbnNwYXJlbnQpOwoKICAmX190aXRsZSB7CiAgICBjb2xvcjogJGFjY2VudDsKICB9Cn0KYGBgCgpGb3IgTGVzcywgaW5zdGFsbCBgbGVzc2AgYW5kIHVzZSBgdWkvc3R5bGUubGVzc2AuCgojIyMjIEVtb3Rpb24KCkVtb3Rpb24gZGVwZW5kZW5jaWVzIG1heSBiZSBpbiBgZGVwZW5kZW5jaWVzYCBvciBgZGV2RGVwZW5kZW5jaWVzYDsgVml0ZSBjYW4KYnVuZGxlIHRoZW0gd2hlbiB0aGV5IGFyZSBpbnN0YWxsZWQgYW5kIGltcG9ydGVkIGJ5IHRoZSBwbHVnaW4uCgpGb3IgYHN0eWxlZGAsIG5vIFZpdGUgY29uZmlnIGNoYW5nZSBpcyBuZWVkZWQ6CgpgYGBiYXNoCm5wbSBpIEBlbW90aW9uL3JlYWN0IEBlbW90aW9uL3N0eWxlZApgYGAKCmBgYHRzeAppbXBvcnQgc3R5bGVkIGZyb20gIkBlbW90aW9uL3N0eWxlZCI7Cgpjb25zdCBQYW5lbCA9IHN0eWxlZC5kaXYoewogIGRpc3BsYXk6ICJncmlkIiwKICBnYXA6IDEyLAp9KTsKYGBgCgpGb3IgRW1vdGlvbidzIGBjc3NgIHByb3AsIHBhc3MgUmVhY3QgcGx1Z2luIG9wdGlvbnMgdGhyb3VnaCBgbXVzY2F0KClgIGFuZCBhZGQKYGpzeEltcG9ydFNvdXJjZWAgdG8gYHRzY29uZmlnLmpzb25gOgoKYGBgYmFzaApucG0gaSBAZW1vdGlvbi9yZWFjdCBAZW1vdGlvbi9zdHlsZWQKbnBtIGkgLUQgQGVtb3Rpb24vYmFiZWwtcGx1Z2luCmBgYAoKYGBgdHMKLy8gdml0ZS5jb25maWcudHMKaW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAidml0ZSI7CmltcG9ydCB0YWlsd2luZGNzcyBmcm9tICJAdGFpbHdpbmRjc3Mvdml0ZSI7CmltcG9ydCB7IG11c2NhdCB9IGZyb20gIkByYWluYm93LXJvYm90aWNzL211c2NhdC1wbHVnaW4ta2l0L3ZpdGUiOwoKZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHsKICBwbHVnaW5zOiBbCiAgICB0YWlsd2luZGNzcygpLAogICAgbXVzY2F0KHsKICAgICAgcmVhY3Q6IHsKICAgICAgICBqc3hJbXBvcnRTb3VyY2U6ICJAZW1vdGlvbi9yZWFjdCIsCiAgICAgICAgYmFiZWw6IHsKICAgICAgICAgIHBsdWdpbnM6IFsiQGVtb3Rpb24vYmFiZWwtcGx1Z2luIl0sCiAgICAgICAgfSwKICAgICAgfSwKICAgIH0pLAogIF0sCn0pOwpgYGAKCmBgYGpzb24KewogICJjb21waWxlck9wdGlvbnMiOiB7CiAgICAianN4SW1wb3J0U291cmNlIjogIkBlbW90aW9uL3JlYWN0IgogIH0KfQpgYGAKCkVtb3Rpb24gYEdsb2JhbGAgd3JpdGVzIGdsb2JhbCBDU1MgYXQgcnVudGltZSwgc28gc2NvcGUgaXQgbWFudWFsbHkgb3IgYXZvaWQgaXQKaW5zaWRlIHBsdWdpbnMuCgojIyMgdXNlUmIoKSBob29rCgpBY2Nlc3MgdGhlIGNvbW11bmljYXRpb24gQVBJIGJldHdlZW4gdGhlIHBsdWdpbiBtb2R1bGUgYW5kIFVJIGZyb20gYW55IHBsdWdpbiBjb21wb25lbnQuCgpgYGB0c3gKaW1wb3J0IHsgdXNlUmIgfSBmcm9tICJAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWkvc2RrIjsKCmZ1bmN0aW9uIEFwcCgpIHsKICBjb25zdCByYiA9IHVzZVJiKCk7Cn0KYGBgCgojIyMgcmIgQVBJCgp8IE1ldGhvZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IERlc2NyaXB0aW9uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAp8IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB8IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gfAp8IGByYi5wdWIodG9waWMsIHBheWxvYWQpYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFB1Ymxpc2ggYSBtZXNzYWdlIHRvIGEgdG9waWMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAp8IGByYi5zdWIodG9waWMsIGhhbmRsZXIpYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFN1YnNjcmliZSB0byBhIHRvcGljIOKAlCByZXR1cm5zIGB7IHVuZGVjbGFyZSgpIH1gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLmFjdGlvbih0b3BpYywgcGF5bG9hZD8pYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU2VuZCBhIHJlcXVlc3QgYW5kIGF3YWl0IGEgcmVwbHkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLnNlcnZlKHRvcGljLCBoYW5kbGVyKWAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgSGFuZGxlIGluY29taW5nIHJlcXVlc3RzIGZyb20gdGhlIGJhY2tlbmQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLnRvYXN0KHsgdGl0bGU/LCBtZXNzYWdlLCB0eXBlPywgYWN0aW9uTGFiZWw/LCBoYW5kbGVBY3Rpb25DbGljaz8sIGNsb3NlT25BY3Rpb25DbGljaz8sIGR1cmF0aW9uPywgb25DbG9zZT8gfSlgIHwgU2hvdyBhIGhvc3QgdG9hc3Qgbm90aWZpY2F0aW9uLiBgbWVzc2FnZWAgYWNjZXB0cyBhIHN0cmluZyBvciBgUmVhY3RFbGVtZW50YC4gYHR5cGVgIGNhbiBiZSBgImluZm8iYCwgYCJkYW5nZXIiYCwgYCJ3YXJuaW5nImAsIGAiY2F1dGlvbiJgLCBvciBgInN1Y2Nlc3MiYCB8CnwgYHJiLmFsZXJ0KHsgdGl0bGU/LCBtZXNzYWdlLCBidXR0b25UZXh0PyB9KWAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU2hvdyBhIGhvc3QgYWxlcnQgZGlhbG9nLiBSZXNvbHZlcyB3aGVuIHRoZSBkaWFsb2cgaXMgY2xvc2VkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLmNvbmZpcm0oeyB0aXRsZT8sIG1lc3NhZ2UsIGJ1dHRvblRleHQ/IH0pYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU2hvdyBhIGhvc3QgY29uZmlybWF0aW9uIGRpYWxvZy4gYGJ1dHRvblRleHRgIGFjY2VwdHMgYHsgeWVzLCBubyB9YC4gUmVzb2x2ZXMgdG8gYHRydWVgIG9yIGBmYWxzZWAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLnByb21wdCh7IHRpdGxlPywgbWVzc2FnZSwgdmFsdWU/LCBwbGFjZWhvbGRlcj8sIGJ1dHRvblRleHQ/IH0pYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU2hvdyBhIGhvc3QgcHJvbXB0IGRpYWxvZy4gYGJ1dHRvblRleHRgIGFjY2VwdHMgYHsgeWVzLCBubyB9YC4gUmVzb2x2ZXMgdG8gdGhlIGVudGVyZWQgc3RyaW5nIG9yIGB1bmRlZmluZWRgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CgpUb3BpYyBuYW1lcyBwYXNzZWQgdG8gYHB1YmAsIGBzdWJgLCBgYWN0aW9uYCwgYW5kIGBzZXJ2ZWAgYXJlIGlzb2xhdGVkIHBlciBwbHVnaW4uCgoKQWxsIG1ldGhvZHMgc3VwcG9ydCBHZW5lcmljIFR5cGVzOgoKYGBgdHN4CmNvbnN0IHN0YXR1cyA9IGF3YWl0IHJiLmFjdGlvbjx7IG9rOiBib29sZWFuIH0sIHsgaWQ6IG51bWJlciB9PigKICAiZ2V0LXN0YXR1cyIsCiAgeyBpZDogMSB9LAopOwoKY29uc3Qgc3ViID0gYXdhaXQgcmIuc3ViPHsgdmFsdWU6IG51bWJlciB9Pigic2Vuc29yL2RhdGEiLCAoZGF0YSkgPT4gewogIGNvbnNvbGUubG9nKGRhdGEudmFsdWUpOwp9KTsKc3ViLnVuZGVjbGFyZSgpOyAvLyBjbGVhbnVwCgpjb25zdCBvayA9IGF3YWl0IHJiLmNvbmZpcm0oewogIHRpdGxlOiAiUnVuIiwKICBtZXNzYWdlOiAiU3RhcnQgdGhlIGJhY2tlbmQgYWN0aW9uPyIsCn0pOwppZiAob2spIHsKICBhd2FpdCByYi5hY3Rpb24oInJ1biIpOwp9CmBgYAoKIyMjIFNhdmluZyBhbmQgcmVzdG9yaW5nIGZvcm0gZGF0YSAoYHVzZVJiRm9ybURhdGFgIC8gYHVzZVJiU2F2ZWApCgpJZiB0aGUgaG9zdCBlbWJlZHMgeW91ciBwbHVnaW4gaW4gYSBmb3JtIGl0IG93bnMgKGUuZy4gYSBwcm9ncmFtIHN0ZXAgZWRpdG9yCndpdGggaXRzIG93biBTYXZlIGJ1dHRvbiksIGl0IGNhbiBoYW5kIHlvdXIgcGx1Z2luIHByZXZpb3VzbHktc2F2ZWQgdmFsdWVzIGFuZApwdWxsIHRoZSBjdXJyZW50IHZhbHVlcyBiYWNrIG91dCB3aGVuIHRoZSB1c2VyIHNhdmVzLiBUaGUgaG9zdCDigJQgbm90IHRoZQpwbHVnaW4g4oCUIHBlcnNpc3RzIHRoZSBkYXRhIChJbmRleGVkREIsIGJhY2tlbmQsIGV0Yy4pLgoKYGBgdHN4CmltcG9ydCB7IHVzZVN0YXRlIH0gZnJvbSAicmVhY3QiOwppbXBvcnQgeyB1c2VSYkZvcm1EYXRhLCB1c2VSYlNhdmUgfSBmcm9tICJAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWkvcmVhY3QiOwoKdHlwZSBHcmlwQXJncyA9IHsgdGFyZ2V0TmFtZTogc3RyaW5nOyB3aWR0aDogbnVtYmVyIH07CmNvbnN0IERFRkFVTFRTOiBHcmlwQXJncyA9IHsgdGFyZ2V0TmFtZTogIiIsIHdpZHRoOiAyMCB9OwoKZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQXBwKCkgewogIC8vIFByZXZpb3VzbHktc2F2ZWQgdmFsdWVzLCBvciB1bmRlZmluZWQgZm9yIGEgYnJhbmQtbmV3IGluc3RhbmNlLgogIGNvbnN0IHNhdmVkID0gdXNlUmJGb3JtRGF0YTxHcmlwQXJncz4oKTsKICBjb25zdCBbYXJncywgc2V0QXJnc10gPSB1c2VTdGF0ZTxHcmlwQXJncz4oeyAuLi5ERUZBVUxUUywgLi4uc2F2ZWQgfSk7CgogIC8vIFJlZ2lzdGVycyBhIGdldHRlciB0aGUgaG9zdCBjYWxscyB3aGVuIGl0cyBTYXZlIGJ1dHRvbiBpcyBjbGlja2VkLgogIC8vIEFsd2F5cyByZXR1cm5zIHRoZSBDVVJSRU5UIHZhbHVlcyDigJQgcmUtcmVnaXN0ZXJpbmcgb24gZXZlcnkgcmVuZGVyIGtlZXBzCiAgLy8gdGhlIGNsb3N1cmUgZnJlc2gsIHdoaWNoIHVzZVJiU2F2ZSBhbHJlYWR5IGhhbmRsZXMgZm9yIHlvdS4KICB1c2VSYlNhdmUoKCkgPT4gKHsKICAgIGFyZ3MsCiAgICBzdW1tYXJ5OiBgJHthcmdzLnRhcmdldE5hbWUgfHwgInRhcmdldCJ9IMK3ICR7YXJncy53aWR0aH1tbWAsCiAgfSkpOwoKICByZXR1cm4gKC8qIC4uLmZvcm0gVUkgcmVhZGluZy93cml0aW5nIGBhcmdzYC4uLiAqLyk7Cn0KYGBgCgpUaGUgdmFsdWUgcmV0dXJuZWQgZnJvbSBgdXNlUmJTYXZlYCBtdXN0IGJlIEpTT04tc2VyaWFsaXNhYmxlIOKAlCB0aGUgaG9zdApwZXJzaXN0cyBpdCBhcy1pcy4gTm90IGV2ZXJ5IGhvc3QgZW1iZWRzIHBsdWdpbnMgaW4gYSBzYXZlL3Jlc3RvcmUgZm9ybTsgaWYKeW91cnMgZG9lc24ndCwgeW91IGNhbiBza2lwIHRoZXNlIGhvb2tzIGVudGlyZWx5LgoKIyMjIFVJIGNvbXBvbmVudHMKCkltcG9ydCBNdXNjYXQgY29tcG9uZW50cyBmcm9tIGBAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWkvcmVhY3RgIGFuZCBleHBvcnQgYQpSZWFjdCBjb21wb25lbnQgYXMgdGhlIGRlZmF1bHQgZXhwb3J0LiBUaGUgaG9zdCBtb3VudHMgdGhhdCBjb21wb25lbnQgZGlyZWN0bHkKYW5kIHByb3ZpZGVzIGB1c2VSYigpYCB0aHJvdWdoIGNvbnRleHQuCgpgYGB0c3gKaW1wb3J0IHsgdXNlU3RhdGUgfSBmcm9tICJyZWFjdCI7CmltcG9ydCB7IFJCTGFiZWxCdXR0b24sIFJCU2xpZGVyLCBSQlN3aXRjaCB9IGZyb20gIkByYWluYm93LXJvYm90aWNzL3BsdWdpbi11aS9yZWFjdCI7CmltcG9ydCB7IHVzZVJiIH0gZnJvbSAiQHJhaW5ib3ctcm9ib3RpY3MvcGx1Z2luLXVpL3NkayI7CgpleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBBcHAoKSB7CiAgY29uc3QgcmIgPSB1c2VSYigpOwogIGNvbnN0IFt3aWR0aCwgc2V0V2lkdGhdID0gdXNlU3RhdGUoMjApOwogIGNvbnN0IFtlbmFibGVkLCBzZXRFbmFibGVkXSA9IHVzZVN0YXRlKHRydWUpOwoKICByZXR1cm4gKAogICAgPGRpdiBjbGFzc05hbWU9ImZsZXggZmxleC1jb2wgZ2FwLTQiPgogICAgICA8UkJTbGlkZXIKICAgICAgICB2YWx1ZT17W3dpZHRoXX0KICAgICAgICBtaW49ezB9CiAgICAgICAgbWF4PXsxMDB9CiAgICAgICAgb25WYWx1ZUNoYW5nZT17KHZhbHVlczogbnVtYmVyW10pID0+IHNldFdpZHRoKHZhbHVlc1swXSA/PyAwKX0KICAgICAgLz4KICAgICAgPFJCU3dpdGNoIGNoZWNrZWQ9e2VuYWJsZWR9IG9uQ2hlY2tlZENoYW5nZT17c2V0RW5hYmxlZH0gLz4KICAgICAgPFJCTGFiZWxCdXR0b24KICAgICAgICBkaXNhYmxlZD17IWVuYWJsZWR9CiAgICAgICAgb25DbGljaz17KCkgPT4gcmIuYWN0aW9uKCJncmlwIiwgeyB3aWR0aCB9KX0KICAgICAgPgogICAgICAgIEdyaXAKICAgICAgPC9SQkxhYmVsQnV0dG9uPgogICAgPC9kaXY+CiAgKTsKfQpgYGAKCi0tLQoKIyMgRGV2ZWxvcGluZyBkaXJlY3RseSBvbiB0aGUgcm9ib3QgUEMKCklmIHlvdSdyZSBydW5uaW5nIGBtdXNjYXQtcGsgZGV2YCAqKm9uIHRoZSByb2JvdCBQQyBpdHNlbGYqKiwgTXVzY2F0IGFscmVhZHkgc2VydmVzIHRoZQpwbHVnaW4gZ2F0ZXdheSBvbiBwb3J0IDEwMDAwLiBUaGUgQ0xJIHNlZXMgdGhhdCwgZG9lcyBub3Qgc3RhcnQgaXRzIG93biBsb2NhbCBNdXNjYXQsIGFuZAp5b3VyIHBsdWdpbiBiYWNrZW5kIGNvbm5lY3RzIHRvIHRoZSByb2JvdCdzIGdhdGV3YXkg4oCUIGV4YWN0bHkgd2hhdCB5b3Ugd2FudCB3aGVuCmRldmVsb3Bpbmcgb24gdGhlIHJvYm90LgoKLS0tCgojIyBTZXZlcmFsIGRldmVsb3BlcnMgb24gb25lIHJvYm90CgpBZ2FpbnN0IGEgcmVtb3RlIHJvYm90LCBgbXVzY2F0LXBrIGRldmAgLyBgZGV2OmJhY2tgIHJ1biB5b3VyIHBsdWdpbiB1bmRlciBhIGRldiBpZCBvZiBpdHMgb3duLApgPG1hbmlmZXN0IGlkPi5kZXYtPHVzZXI+LTxyYW5kb20+YCAocHJpbnRlZCBhdCBzdGFydDsgdGhlIHJhbmRvbSBwYXJ0IGlzIGtlcHQgaW4gYH4vLm11c2NhdC1way9kZXYtaWRgKS4KVHdvIG1hY2hpbmVzIGRldmVsb3BpbmcgdGhlIHNhbWUgcGx1Z2luIG9uIG9uZSByb2JvdCB3b3VsZCBvdGhlcndpc2UgcmVnaXN0ZXIgdGhlIHNhbWUgdG9waWNzIG9uIGl0cwpnYXRld2F5LCBhbmQgYSBidXR0b24gaW4gb25lIFVJIHdvdWxkIHNpbGVudGx5IHJ1biB0aGUgb3RoZXIgbWFjaGluZSdzIGJhY2tlbmQuIFRoZSBVSSwgdGhlIGJhY2tlbmQsCnRoZSBST1MgbmFtZXNwYWNlIGFuZCBleHRlcm5hbCByb3V0ZXMgKGBjb21tb24vcGx1Z2luLzxkZXYgaWQ+LzxwYXRoPmApIGFsbCB1c2UgdGhlIGRldiBpZC4KClBhc3MgYC0ta2VlcC1pZGAgdG8gcnVuIHVuZGVyIHRoZSBtYW5pZmVzdCBpZCBpbnN0ZWFkLCBlLmcuIHRvIHRlc3QgcHJvZ3JhbSBgZXhlY3V0ZWAgb3IgYW4gZXh0ZXJuYWwKY2xpZW50IHRoYXQgdXNlcyB0aGUgcmVhbCBpZC4gVGhlbiBvbmx5IG9uZSBtYWNoaW5lIG1heSBiZSBjb25uZWN0ZWQgdG8gdGhhdCByb2JvdC4KCi0tLQoKIyMgQmFja2VuZCBydW50aW1lcwoKYG1hbmlmZXN0Lmpzb25gIGNob29zZXMgb25lIGJhY2tlbmQgcnVudGltZS4gYG11c2NhdC1wayBkZXZgIHJ1bnMgYmFja2VuZCBjb2RlIGluCmEgRG9ja2VyIGNvbnRhaW5lciBtYXRjaGluZyB0aGUgcm9ib3QgZW52aXJvbm1lbnQuIEJhY2tlbmQgY29kZSBzaG91bGQgY29udGFpbgpwbHVnaW4gbG9naWMgb25seTsgaXQgc2hvdWxkIG5vdCBzdGFydCBpdHMgb3duIGNvcHkgb2YgdGhlIHBsdWdpbiBnYXRld2F5LgoKIyMjIFdoaWNoIGJhY2tlbmQgcGF0dGVybj8gKGRlcGVuZHMgb24gdGhlIGNvbnRyaWJ1dGlvbiBwb2ludCkKCioqSG93IHlvdSBjb250cm9sIHRoZSByb2JvdCBkZXBlbmRzIG9uIHdoYXQgeW91ciBwbHVnaW4gY29udHJpYnV0ZXMqKiAoc2VlCmBtYW5pZmVzdC5qc29uYCDihpIgYGNvbnRyaWJ1dGVzW10ucG9pbnRgKS4gRG9uJ3QgbWl4IHRoZXNlIHVwOgoKfCBDb250cmlidXRpb24gcG9pbnQgfCBXaGF0IGl0IGlzIHwgQmFja2VuZCBwYXR0ZXJuIHwKfCAtLS0gfCAtLS0gfCAtLS0gfAp8IGBwcm9ncmFtLnBhbmVsYCAod2l0aCBgY29tbWFuZEluZm9gKSB8IERlZmluZXMgYSAqKmN1c3RvbSBjb21tYW5kKiogdGhlIHBsdWdpbiBhZGRzIHRvIHRoZSBQcm9ncmFtIHBhZ2UncyBydWxlLWJhc2VkIHNlcXVlbmNlIGJ1aWxkZXIuIFRoZSBvcGVyYXRvciBwbGFjZXMgaXQgaW50byB0aGUgcHJvZ3JhbSB0cmVlIGxpa2UgYW55IGJ1aWx0LWluIGNvbW1hbmQgKE1vdmUgSiwgUG9pbnQsIFdhaXQsIOKApik7IGl0IHJ1bnMgd2hlbiB0aGUgcHJvZ3JhbSByZWFjaGVzIHRoYXQgc3RlcC4gfCAqKmBQbHVnaW5Qcm9ncmFtQ29udGV4dGAqKiDigJQgaW50ZWdyYXRlZCB3aXRoIHRoZSBwcm9ncmFtJ3Mgc3RvcC9wYXVzZSBhbmQgdmFyaWFibGVzLiBTZWUgX1Byb2dyYW0gY29tbWFuZCBiYWNrZW5kXyBiZWxvdy4gfAp8IGB0b29sYmFyYCAvIGBsbmJgIC8gYG1vdmUucGFuZWxgIHwgQSBsaXZlIFVJIHBhbmVsL3BvcG92ZXIgdGhlIG9wZXJhdG9yIGludGVyYWN0cyB3aXRoIGRpcmVjdGx5IHwgQ2FsbCB0aGUgcm9ib3QgKipTREsgZGlyZWN0bHkqKiAoYFJCTWFuaXB1bGF0ZVNES2ApIGZyb20gYGNwcC9tYWluLmNwcGAsIG9yIGByYi5hY3Rpb24oLi4uKWAg4oaSIHlvdXIgYmFja2VuZCDihpIgU0RLLiAqKk5vdCoqIGEgcHJvZ3JhbSBzdGVwIOKAlCB0aGVyZSBpcyBubyBzdG9wL3BhdXNlL3ZhcmlhYmxlIGNvbnRleHQuIHwKClJ1bGUgb2YgdGh1bWI6IHVzZSBgUGx1Z2luUHJvZ3JhbUNvbnRleHRgICoqb25seSoqIGZvciBhIGBwcm9ncmFtLnBhbmVsYCBjb21tYW5kCnRoYXQgcnVucyBhcyBwYXJ0IG9mIGEgcHJvZ3JhbS4gVG8gbW92ZSB0aGUgcm9ib3QgbGl2ZSBmcm9tIGEgdG9vbGJhci9tb3ZlIHBhbmVsLAp1c2UgdGhlIFNESyDigJQgYSBwcm9ncmFtLXN0ZXAgY29udGV4dCBkb2VzIG5vdCBhcHBseS4KCiMjIyBGcm9udGVuZC1vbmx5IChgbm9uZWApCgpVc2UgdGhpcyB3aGVuIHRoZSBwbHVnaW4gb25seSBoYXMgVUkgYW5kIGNhbGxzIGhvc3Qgc2VydmljZXM6CgpgYGBqc29uCnsgInJ1bnRpbWUiOiB7ICJ0eXBlIjogIm5vbmUiIH0gfQpgYGAKCiMjIyBDKysgKGBjcHBgKQoKQysrIHBsdWdpbnMgYnVpbGQgYGNwcC9gIHdpdGggQ01ha2UgYW5kIHJ1biB0aGUgZXhlY3V0YWJsZSBuYW1lZCBieQpgbWFuaWZlc3QuanNvbmAg4oaSIGBydW50aW1lLmVudHJ5YC4gVGhlIFJhaW5ib3cgUm9ib3RpY3MgQysrIFNESwooYHJhaW5ib3ctcmItc2RrLWRldmApIGlzIHByZS1pbnN0YWxsZWQgaW4gdGhlIGBtdXNjYXQtcGtgIGRldiBjb250YWluZXIg4oCUIHlvdQpkb24ndCBpbnN0YWxsIGFueXRoaW5nIGxvY2FsbHkuCgpgYGBqc29uCnsgInJ1bnRpbWUiOiB7ICJ0eXBlIjogImNwcCIsICJlbnRyeSI6ICJfX1BMVUdJTl9TTFVHX18iIH0gfQpgYGAKCmBgYGNtYWtlCiMgY3BwL0NNYWtlTGlzdHMudHh0IOKAlCB0aGUgdmVyc2lvbiBpcyB0aGUgU0RLIHRoZSBkZXYgY29udGFpbmVyIGluc3RhbGxzIChtdXNjYXQtcGsgc2RrIHVwZGF0ZSA8dmVyc2lvbj4pCmZpbmRfcGFja2FnZShyYl9zZGsgMC4xMC4yIEVYQUNUIFJFUVVJUkVEKQphZGRfZXhlY3V0YWJsZShfX1BMVUdJTl9TTFVHX18gbWFpbi5jcHApICAgICAgICAgICAjIG5hbWUgbXVzdCBlcXVhbCBydW50aW1lLmVudHJ5CnRhcmdldF9saW5rX2xpYnJhcmllcyhfX1BMVUdJTl9TTFVHX18gUFJJVkFURSByYl9zZGs6OnJiX3NkaykKYGBgCgpFZGl0b3Igc3VwcG9ydDogdGhlIFNESyBpcyBpbnN0YWxsZWQgb25seSBpbnNpZGUgdGhlIGRldiBjb250YWluZXIsIHNvIGBtdXNjYXQtcGsgbmV3YCAoYW5kIGxhdGVyCmBkZXZgIC8gYGJ1aWxkYCAvIGB0eXBlIGNoYW5nZWApIGNvcGllcyBpdHMgaGVhZGVycyB0byBgLm11c2NhdC1kZXYvc3lzcm9vdGAgYW5kIHdyaXRlcyBhIGBNdXNjYXRgCmNvbmZpZ3VyYXRpb24gdG8gYC52c2NvZGUvY19jcHBfcHJvcGVydGllcy5qc29uYC4gVlMgQ29kZSdzIEMvQysrIGV4dGVuc2lvbiB0aGVuIHJlc29sdmVzIGByYl9zZGtgCm5hbWVzLiBUaGUgY29waWVzIGZvbGxvdyB0aGUgU0RLIHZlcnNpb24gYWJvdmU7IHRoZSBidWlsZCBpdHNlbGYgbmV2ZXIgdXNlcyB0aGVtLiBST1MgMiBoZWFkZXJzCihgcmNsY3BwYCkgYXJlIG5vdCBjb3BpZWQuCgpIZWFkZXJzIGxpdmUgdW5kZXIgYDxyYWluYm93L3JiX3Nkay8uLi4+YDoKCnwgSGVhZGVyIHwgQ2xhc3MgfCBVc2UgfAp8IC0tLSB8IC0tLSB8IC0tLSB8CnwgYHBsdWdpbi9yYl9wbHVnaW4uaHBwYCB8IGByYl9wbHVnaW46OlJCUGx1Z2luQ2FsbGAgfCBwbHVnaW4gVUkg4oaUIGJhY2tlbmQsIGV4dGVybmFsIGVuZHBvaW50cyAoYHJvdXRlcigpYCkgfAp8IGBtYW5pcHVsYXRlL3JiX21hbmlwdWxhdGVfc2RrLmhwcGAgfCBgUkJNYW5pcHVsYXRlU0RLYCB8IGNvbnRyb2wgYSBtYW5pcHVsYXRvciB8CnwgYHByb2dyYW0vcmJfcHJvZ3JhbV9zZGsuaHBwYCB8IGBSQlByb2dyYW1TREtgIHwgcHJvZ3JhbS1zaWRlIGhlbHBlcnMgfAp8IGBwcm9ncmFtL3BsdWdpbl9wcm9ncmFtX2NvbnRleHQuaHBwYCB8IGByYl9wbHVnaW46OlBsdWdpblByb2dyYW1Db250ZXh0YCB8IGBwcm9ncmFtLnBhbmVsYCBjb21tYW5kcyB8CnwgYHplbm9oX2NsaWVudC5ocHBgIHwgYFplbm9oQ2xpZW50YCB8IGxvdy1sZXZlbCBwdWIvc3ViL3F1ZXJ5IHwKClBheWxvYWRzIGFyZSBgbmxvaG1hbm46Ompzb25gIChgI2luY2x1ZGUgPG5sb2htYW5uL2pzb24uaHBwPmAsIGluc3RhbGxlZCB3aXRoIHRoZSBTREspLgoKIyMjIyBUYWxraW5nIHRvIHRoZSBwbHVnaW4gVUkgKGBSQlBsdWdpbkNhbGxgKQoKYGBgY3BwCiNpbmNsdWRlIDxyYWluYm93L3JiX3Nkay9wbHVnaW4vcmJfcGx1Z2luLmhwcD4KI2luY2x1ZGUgPG5sb2htYW5uL2pzb24uaHBwPgoKdXNpbmcgbmxvaG1hbm46Ompzb247CnVzaW5nIHJiX3BsdWdpbjo6UkJQbHVnaW5DYWxsOwoKaW50IG1haW4oKSB7CiAgLy8gcGx1Z2luIGlkIGNvbWVzIGZyb20gZW52IFJCX1BMVUdJTl9JRCAoc2V0IGJ5IG11c2NhdC1wayBkZXYgYW5kIGJ5IHRoZSByb2JvdCkKICBhdXRvIHBsdWdpbiA9IFJCUGx1Z2luQ2FsbDo6Z2V0X2luc3RhbmNlKFJCUGx1Z2luQ2FsbDo6cmVzb2x2ZV9wbHVnaW5faWQoc3RkOjpudWxsb3B0KSk7CgogIHBsdWdpbi0+cHVibGlzaCgic3RhdGUiLCB7eyJyZWFkeSIsIHRydWV9fSk7ICAgICAgICAgICAgICAgICAvLyBVSTogcmIuc3ViKCJzdGF0ZSIsIC4uLikKCiAgYXV0byBzdWIgPSBwbHVnaW4tPnN1YnNjcmliZSgiZXZlbnQiLCAgICAgICAgICAgICAgICAgICAgICAgIC8vIFVJOiByYi5wdWIoImV2ZW50IiwgLi4uKQogICAgICBbXShjb25zdCBzdGQ6OnN0cmluZyYgdG9waWMsIGNvbnN0IGpzb24mIHBheWxvYWQpIHsgLyogLi4uICovIH0pOwoKICBwbHVnaW4tPnNlcnZlKCJ0b29sL2VjaG8iLCBbXShjb25zdCBqc29uJiBwYXlsb2FkKSB7ICAgICAgICAgLy8gVUk6IGF3YWl0IHJiLmFjdGlvbigidG9vbC9lY2hvIiwgLi4uKQogICAgcmV0dXJuIGpzb257eyJlY2hvIiwgcGF5bG9hZH19OwogIH0pOwoKICBqc29uIHJlcyA9IHBsdWdpbi0+Y2FsbCgidG9vbC9waW5nIiwge3siaGVsbG8iLCAicGx1Z2luIn19LCA1LjApOyAgLy8gVUkgYW5zd2VycyB3aXRoIHJiLnNlcnZlKCJ0b29sL3BpbmciLCAuLi4pCgogIGZvciAoOzspIHN0ZDo6dGhpc190aHJlYWQ6OnNsZWVwX2ZvcihzdGQ6OmNocm9ubzo6c2Vjb25kcygxKSk7ICAgIC8vIHN0YXkgcmVzaWRlbnQKfQpgYGAKCnwgQysrIHwgVUkgKGB1c2VSYigpYCkgfAp8IC0tLSB8IC0tLSB8CnwgYHBsdWdpbi0+c2VydmUodG9waWMsIGZuKWAgfCBgYXdhaXQgcmIuYWN0aW9uKHRvcGljLCBwYXlsb2FkKWAgfAp8IGBwbHVnaW4tPnN1YnNjcmliZSh0b3BpYywgZm4pYCB8IGByYi5wdWIodG9waWMsIHBheWxvYWQpYCB8CnwgYHBsdWdpbi0+cHVibGlzaCh0b3BpYywgcGF5bG9hZClgIHwgYHJiLnN1Yih0b3BpYywgaGFuZGxlcilgIHwKfCBgcGx1Z2luLT5jYWxsKHRvcGljLCBwYXlsb2FkLCB0aW1lb3V0X3NlYylgIHwgYHJiLnNlcnZlKHRvcGljLCBoYW5kbGVyKWAgfAoKLSBLZWVwIHRoZSBgU3Vic2NyaXB0aW9uYCByZXR1cm5lZCBieSBgc3Vic2NyaWJlYDsgcGFzcyBpdCB0byBgcGx1Z2luLT51bnN1YnNjcmliZShzdGQ6Om51bGxvcHQsIHN1YilgIHRvIHJlbW92ZSBqdXN0IHRoYXQgb25lLgotIGBjYWxsYCB0aHJvd3MgYHJiX3BsdWdpbjo6UkJQbHVnaW5HYXRld2F5RXJyb3JgIHdoZW4gdGhlIGdhdGV3YXkgaXMgZG93biBvciB0aGUgVUkgZG9lc24ndCBhbnN3ZXIgaW4gdGltZS4KCiMjIyMgRXh0ZXJuYWwgZW5kcG9pbnRzIChgcm91dGVyKClgKQoKYHNlcnZlYCAvIGBzdWJzY3JpYmVgIC8gYHB1Ymxpc2hgIGFyZSAqKmludGVybmFsIG9ubHkqKiAocGx1Z2luIFVJIOKGlCBiYWNrZW5kKS4KVG8gZXhwb3NlIGFuIGVuZHBvaW50IHRvIHRoZSBvdXRzaWRlIHdvcmxkIOKAlCBSRVNULCBTb2NrZXQuSU8sIFRDUCwgTVFUVCwKV2ViUlRDIOKAlCB1c2UgYHBsdWdpbi0+cm91dGVyKClgLiBUaGUgcnVubmluZyBNdXNjYXQgKGBjb21tb25gKSBwaWNrcyBpdCB1cAp3aXRob3V0IGEgcmVzdGFydCwgYW5kIGl0IGRpc2FwcGVhcnMgd2hlbiB0aGUgcGx1Z2luIHN0b3BzLgoKYGBgY3BwCmF1dG8mIHJvdXRlciA9IHBsdWdpbi0+cm91dGVyKCk7Cgpyb3V0ZXIub24oIi9oZWxsbyIsIFtdKGNvbnN0IGpzb24mIHBheWxvYWQsIGNvbnN0IGpzb24mIG1ldGEpIHsgICAgICAgLy8gYWxsIDUgdHJhbnNwb3J0cwogIHJldHVybiBqc29ue3sibXNnIiwgImhpICIgKyBwYXlsb2FkLnZhbHVlKCJuYW1lIiwgc3RkOjpzdHJpbmcoInRoZXJlIikpfX07Cn0pOwoKcm91dGVyLm9uKCIvYWRtaW4iLCBbXShjb25zdCBqc29uJiBwYXlsb2FkLCBjb25zdCBqc29uJiBtZXRhKSB7CiAgaWYgKCFtZXRhLnZhbHVlKCJwcmluY2lwYWwiLCBqc29uOjpvYmplY3QoKSkudmFsdWUoImlzX2FkbWluIiwgZmFsc2UpKQogICAgdGhyb3cgcmJfcGx1Z2luOjpQbHVnaW5Sb3V0ZUVycm9yKDQwMywgImFkbWluIG9ubHkiKTsgICAgICAgICAgICAgIC8vIGJlY29tZXMgdGhlIGV4dGVybmFsIHN0YXR1cwogIHJldHVybiBqc29uOjpvYmplY3QoKTsKfSwgc3RkOjp2ZWN0b3I8c3RkOjpzdHJpbmc+eyJhcGkifSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJFU1Qgb25seQoKcm91dGVyLnN1YnNjcmliZSgiL2NtZCIsIFtdKGNvbnN0IGpzb24mIHBheWxvYWQpIHsgLyogLi4uICovIH0sCiAgICAgICAgICAgICAgICAgc3RkOjp2ZWN0b3I8c3RkOjpzdHJpbmc+eyJ0Y3AifSk7ICAgICAgICAgICAgICAgICAgICAvLyByZWNlaXZlIGV4dGVybmFsIFRDUCBwdWJsaXNoCgpyb3V0ZXIuZW1pdCgiL3N0YXRlIiwge3siYnVzeSIsIHRydWV9fSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHB1c2ggdG8gZXh0ZXJuYWwgc3Vic2NyaWJlcnMKYGBgCgpgYGBiYXNoCmN1cmwgLXMgLVggUE9TVCBodHRwOi8vPHJvYm90Pi9jb21tb24vcGx1Z2luLzxwbHVnaW5faWQ+L2hlbGxvIFwKICAtSCAnQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9qc29uJyAtZCAneyJuYW1lIjoia2ltIn0nCiMg4oaSIHsibXNnIjoiaGkga2ltIn0KYGBgCgp8IEFQSSB8IE1lYW5pbmcgfCBFeHRlcm5hbCBhZGRyZXNzIHwKfCAtLS0gfCAtLS0gfCAtLS0gfAp8IGByb3V0ZXIub24ocGF0aCwgaGFuZGxlciwgZXhwbGljaXRfcm91dGVzKWAgfCByZXF1ZXN0L3Jlc3BvbnNlIGhhbmRsZXIgfCBgY29tbW9uL3BsdWdpbi97cGx1Z2luX2lkfS97cGF0aH1gIChSRVNUIGlzIGFsd2F5cyBgUE9TVGApIHwKfCBgcm91dGVyLnN1YnNjcmliZSh0b3BpYywgaGFuZGxlciwgZXhwbGljaXRfZXZlbnRzKWAgfCByZWNlaXZlIGV4dGVybmFsIHB1Ymxpc2hlcyB8IGV4dGVybmFsIHNpZGUgcHVibGlzaGVzIHRvIGBjb21tb24vcGx1Z2luL3twbHVnaW5faWR9L3t0b3BpY31gIHwKfCBgcm91dGVyLmVtaXQodG9waWMsIHBheWxvYWQpYCB8IHBsdWdpbiDihpIgZXh0ZXJuYWwgcHVzaCB8IGV4dGVybmFsIHNpZGUgc3Vic2NyaWJlcyB0byBgY29tbW9uL3BsdWdpbi97cGx1Z2luX2lkfS97dG9waWN9YCB8CgotIGBtZXRhYCA9IGB7InRyYW5zcG9ydCI6ICJhcGkifCJzb2NrZXQifCJ0Y3AifCJtcXR0Inwid2VicnRjIiwgInByaW5jaXBhbCI6IG9iamVjdCB8IG51bGx9YC4gKipSb2xlIGNoZWNrcyBhcmUgdGhlIHBsdWdpbidzIGpvYi4qKgotIFRyYW5zcG9ydCBuYW1lczogYGFwaSB8IHNvY2tldCB8IHRjcCB8IG1xdHQgfCB3ZWJydGNgOyBgc3Vic2NyaWJlYCBhY2NlcHRzIG9ubHkgYHRjcCB8IG1xdHQgfCB3ZWJydGNgLiBVbmtub3duIG5hbWVzIG9yIGR1cGxpY2F0ZSBwYXRocyB0aHJvdyBgc3RkOjppbnZhbGlkX2FyZ3VtZW50YC4KLSBUaHJvdyBgcmJfcGx1Z2luOjpQbHVnaW5Sb3V0ZUVycm9yKGNvZGUsIG1lc3NhZ2UpYCB0byBzZXQgdGhlIHN0YXR1czsgYW55IG90aGVyIGV4Y2VwdGlvbiDihpIgNTAwLgoKfCBTaXR1YXRpb24gfCBTdGF0dXMgfAp8IC0tLSB8IC0tLSB8CnwgTm8gcGx1Z2luIGRlY2xhcmVzIHRoYXQgcGF0aCAvIHBsdWdpbiBpcyBkb3duIC8gdHJhbnNwb3J0IG5vdCBhbGxvd2VkIHwgNDA0IHwKfCBQbHVnaW4gZGlkIG5vdCBhbnN3ZXIgd2l0aGluIDEwIHMgfCA1MDQgfAp8IGBjb21tb25gIOKGlCBnYXRld2F5IG5vdCBjb25uZWN0ZWQgfCA1MDMgfAoKRHVyaW5nIGBtdXNjYXQtcGsgZGV2YCB0aGUgbG9jYWwgTXVzY2F0IHJ1bnRpbWUgdGFrZXMgYHJvdXRlcigpYCByZWdpc3RyYXRpb25zIG9uIGl0cwpnYXRld2F5IGFuZCBpdHMgYGNvbW1vbmAgcm91dGVzIGV4dGVybmFsIGNhbGxzIHRvIHRoZW0gbGlrZSBvbiB0aGUgcm9ib3QKKGBjdXJsIGh0dHA6Ly9sb2NhbGhvc3Q6MzAwMC9jb21tb24vcGx1Z2luLzxwbHVnaW4taWQ+LzxwYXRoPmApLiBBZnRlcgpyZXN0YXJ0aW5nIHRoZSBwbHVnaW4sIGV4dGVybmFsIGNhbGxzIG1heSByZXR1cm4gNTA0IGZvciBhYm91dCBhIG1pbnV0ZSwgdGhlbiA0MDQuCgojIyMjIFByb2dyYW0gY29tbWFuZCBiYWNrZW5kIChgcHJvZ3JhbS5wYW5lbGApCgpBIGBwcm9ncmFtLnBhbmVsYCBjb250cmlidXRpb24gYWRkcyBhICoqY3VzdG9tIGNvbW1hbmQqKiB0byB0aGUgUHJvZ3JhbSBwYWdlLgpFYWNoIHRpbWUgdGhlIHByb2dyYW0gcmVhY2hlcyB0aGF0IHN0ZXAsIHRoZSBob3N0IGNhbGxzIHlvdXIgYmFja2VuZCB0aHJvdWdoCmBQbHVnaW5Qcm9ncmFtQ29udGV4dGAgd2l0aCB0aGUgc3RlcCBhcmdzICh3aGF0IHRoZSBVSSBzYXZlZCB3aXRoIGB1c2VSYlNhdmVgKS4KCmBgYGNwcAojaW5jbHVkZSA8cmFpbmJvdy9yYl9zZGsvcHJvZ3JhbS9wbHVnaW5fcHJvZ3JhbV9jb250ZXh0LmhwcD4KCnVzaW5nIHJiX3BsdWdpbjo6UGx1Z2luUHJvZ3JhbUNvbnRleHQ7CgppbnQgbWFpbigpIHsKICBQbHVnaW5Qcm9ncmFtQ29udGV4dCBjdHgoIl9fUExVR0lOX0lEX18iKTsKCiAgY3R4LnNldF9leGVjdXRlX2hhbmRsZXIoWyZdKGNvbnN0IG5sb2htYW5uOjpqc29uJiBhcmdzKSB7CiAgICBhdXRvIGNvdW50ID0gY3R4LmdldF92YXJpYWJsZSgiY291bnRlciIpOyAgICAgICAgICAgICAgICAgIC8vIGpzb247IG51bGwgaWYgbm8gcHJvZ3JhbSBydW5zCiAgICBjdHguc2V0X3ZhcmlhYmxlKCJjb3VudGVyIiwgY291bnQuaXNfbnVtYmVyKCkgPyBjb3VudC5nZXQ8aW50PigpICsgMSA6IDEpOwogICAgY3R4LnNldF92YXJpYWJsZSgiUkJQX19fUExVR0lOX1NMVUdfX19yZXN1bHQiLCA0Mik7ICAgICAgICAvLyBORVcgdmFyaWFibGVzIG11c3Qgc3RhcnQgd2l0aCBSQlBfCgogICAgdHJ5IHsKICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDA7ICsraSkgewogICAgICAgIGN0eC5jaGVja19zdG9wKCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBwYXVzZSDihpIgYmxvY2tzLCBzdG9wIOKGkiB0aHJvd3MgUGx1Z2luU3RvcHBlZAogICAgICAgIHN0ZDo6dGhpc190aHJlYWQ6OnNsZWVwX2ZvcihzdGQ6OmNocm9ubzo6bWlsbGlzZWNvbmRzKDUwMCkpOwogICAgICB9CiAgICB9IGNhdGNoIChjb25zdCByYl9wbHVnaW46OlBsdWdpblN0b3BwZWQmKSB7CiAgICAgIHJldHVybjsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHByb2dyYW0gd2FzIHN0b3BwZWQKICAgIH0KICAgIGN0eC5kb25lKCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWx3YXlzIGNhbGwg4oCUIHRoZSBzdGVwIGVuZHMgaGVyZQogIH0pOwoKICBjdHguc3RhcnQoKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZG9lcyBub3QgYmxvY2sKICBmb3IgKDs7KSBzdGQ6OnRoaXNfdGhyZWFkOjpzbGVlcF9mb3Ioc3RkOjpjaHJvbm86OnNlY29uZHMoMSkpOwp9CmBgYAoKLSBUaGUgc3RlcCBkb2VzIG5vdCBmaW5pc2ggdW50aWwgeW91IGNhbGwgYGN0eC5kb25lKClgLgotIGBzZXRfZXhlY3V0ZV9oYW5kbGVyYCBtdXN0IGJlIGNhbGxlZCBiZWZvcmUgYHN0YXJ0KClgLgotICoqTmV3KiogdmFyaWFibGVzIG5lZWQgdGhlIGBSQlBfYCBwcmVmaXggKGBSQlBfe3BsdWdpbl9pZH1fe25hbWV9YCByZWNvbW1lbmRlZCk7IGV4aXN0aW5nIG9uZXMgcGFzcyBhcy1pcy4KLSBgZ2V0X3ZhcmlhYmxlKG5hbWUsIHJvYm90X21vZGVsLCBwbHVnaW5faWQpYCDigJQgb3B0aW9uYWwgZmlsdGVyczogYSBzcGVjaWZpYyByb2JvdCwgb3IgdGhlIHZhbHVlIGEgZ2l2ZW4gcGx1Z2luIGxhc3Qgd3JvdGUuCi0gRXhlY3V0b3Igc3RhdGU6IGBjdHguZXhlY3V0b3Jfc3RhdGVfZm9yKCJDNTAwOTIwIilgLCBgY3R4LmV4ZWN1dG9yX3N0YXRlcygpYCwgYGN0eC5pc19wYXVzZWQoKWAsIGBjdHguaXNfc3RvcHBlZCgpYCwKICBvciBgY3R4LnNldF9zdGF0ZV9jaGFuZ2VfaGFuZGxlcihbXShjb25zdCBzdGQ6OnN0cmluZyYgbW9kZWwsIGNvbnN0IHN0ZDo6c3RyaW5nJiBzdGF0ZSkgeyAuLi4gfSlgLgotIEEgbG9uZy1ydW5uaW5nIGhhbmRsZXIgbXVzdCBjYWxsIGBjaGVja19zdG9wKClgIGV2ZXJ5IGl0ZXJhdGlvbiwgb3IgaXQga2VlcHMgcnVubmluZyBhZnRlciB0aGUgb3BlcmF0b3IgcHJlc3NlcyBTdG9wLgoKVmFyaWFibGVzIHRoZSBQcm9ncmFtIHBhZ2UgdmFyaWFibGUgcGlja2VyIHNob3VsZCBvZmZlciBtdXN0IGJlIGRlY2xhcmVkIGluCmBtYW5pZmVzdC5qc29uYCB1bmRlciBgInZhcmlhYmxlcyJgLgoKIyMjIyBDb250cm9sbGluZyB0aGUgcm9ib3QKCmBgYGNwcAojaW5jbHVkZSA8cmFpbmJvdy9yYl9zZGsvbWFuaXB1bGF0ZS9yYl9tYW5pcHVsYXRlX3Nkay5ocHA+CgpSQk1hbmlwdWxhdGVTREsgbWFuaXB1bGF0ZTsgICAgICAgICAgICAgICAgICAgICAgIC8vIG9uIHRoZSByb2JvdDogY29ubmVjdHMgdG8gdGhlIGxvY2FsIFplbm9oCm1hbmlwdWxhdGUuc3RhdGUuY2FsbF9zZXJ2b2NvbnRyb2woIkM1MDA5MjAiLCAxKTsKCklQQzo6TW92ZUlucHV0X1RhcmdldFQgdDsKdC50YXJfdmFsdWVzID0gezAsIDAsIDkwLCAwLCA5MCwgMCwgMH07ICAvLyBqb2ludCBkZWdyZWVzLCBhbHdheXMgNyB2YWx1ZXMgKDd0aCA9IDAgb24gNi1heGlzIGFybXMpCnQudGFyX2ZyYW1lID0gLTE7ICAgICAgICAgICAgICAgICAgICAgICAgLy8gLTEgPSBqb2ludCBzcGFjZQp0LnRhcl91bml0ID0gMDsgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDAgPSBtbS9kZWcKbWFuaXB1bGF0ZS5tb3ZlLmNhbGxfbW92ZV9qKCJDNTAwOTIwIiwgdCwgc3RkOjpudWxsb3B0LCBNb3ZlU3BlZWRBcmd7MSwgNjAuZiwgMTIwLmZ9KTsKbWFuaXB1bGF0ZS5tb3ZlLmNhbGxfbW92ZV93YWl0KCJDNTAwOTIwIiwgLTEpOwpgYGAKClJlbW90ZSBkZXYgKGBtdXNjYXQtcGsgZGV2IC0tcm9ib3QtaXAgPGlwPiBbLS1yb2JvdC10b2tlbiA8dG9rZW4+XWApIHNldHMKYE1VU0NBVF9ST0JPVF9IT1NUYCAvIGBNVVNDQVRfUk9CT1RfVE9LRU5gOyBjb25uZWN0ICoqYmVmb3JlKiogcmVnaXN0ZXJpbmcKc3Vic2NyaXB0aW9ucywgYmVjYXVzZSBgY29ubmVjdCgpYCByZW9wZW5zIHRoZSBaZW5vaCBzZXNzaW9uLiBUaGUgdG9rZW4gaXMKb3B0aW9uYWwg4oCUIGl0IGlzIG5lZWRlZCBvbmx5IHdoZW4gdGhlIHJvYm90J3MgbG9naW4gcG9saWN5IGlzIG9uOgoKYGBgY3BwCmlmIChjb25zdCBjaGFyKiBob3N0ID0gc3RkOjpnZXRlbnYoIk1VU0NBVF9ST0JPVF9IT1NUIikpIHsKICBjb25zdCBjaGFyKiB0b2tlbiA9IHN0ZDo6Z2V0ZW52KCJNVVNDQVRfUk9CT1RfVE9LRU4iKTsKICBtYW5pcHVsYXRlLmNvbm5lY3Qoey50b2tlbiA9IHRva2VuID8gdG9rZW4gOiAiIiwgLmhvc3QgPSBob3N0fSk7Cn0KYGBgCgpBTVIgYW5kIFJCLVkxIFNES3MgYXJlIFB5dGhvbi1vbmx5IGZvciBub3cuCgojIyMgUk9TMiAocmNsY3BwKQoKUk9TMiBDKysgcGx1Z2lucyB1c2UgYHJvczJfd3MvYCB3aXRoIGBydW50aW1lLnJvc0NsaWVudDogInJjbGNwcCJgLiBUaGUgbm9kZQpsaW5rcyB0aGUgQysrIFNESyB0aGUgc2FtZSB3YXkgKGBmaW5kX3BhY2thZ2UocmJfc2RrKWAgKyBgcmJfc2RrOjpyYl9zZGtgKTsgcmVsYXRpdmUgdG9waWMgbmFtZXMgYXJlIHBsYWNlZCB1bmRlciB0aGUgcGx1Z2luJ3MgUk9TIG5hbWVzcGFjZSDigJQgdGhlIHBsdWdpbiBpZAp3aXRoICIuIiDihpIgIi8iIGFuZCAiLSIg4oaSICJfIiAoYGNvbS5leGFtcGxlLm15LXBsdWdpbmAg4oaSIGAvY29tL2V4YW1wbGUvbXlfcGx1Z2luYCksIGluIGRldgphbmQgb24gdGhlIHJvYm90LiBVc2UgYW4gYWJzb2x1dGUgbmFtZSAoYC9jbWRfdmVsYCkgZm9yIHRvcGljcyBzaGFyZWQgd2l0aCBvdGhlciBub2Rlcy4KCmBgYGNwcAojaW5jbHVkZSAicmNsY3BwL3JjbGNwcC5ocHAiCiNpbmNsdWRlIDxyYWluYm93L3JiX3Nkay9tYW5pcHVsYXRlL3JiX21hbmlwdWxhdGVfc2RrLmhwcD4KCmNsYXNzIF9fUExVR0lOX0NMQVNTX19Ob2RlIDogcHVibGljIHJjbGNwcDo6Tm9kZSB7CnB1YmxpYzoKICBfX1BMVUdJTl9DTEFTU19fTm9kZSgpIDogTm9kZSgiX19QTFVHSU5fU0xVR19fX25vZGUiKSB7CiAgICBSQ0xDUFBfSU5GTyh0aGlzLT5nZXRfbG9nZ2VyKCksICJfX1BMVUdJTl9OQU1FX18gbm9kZSBzdGFydGVkIik7CiAgfQp9OwoKaW50IG1haW4oaW50IGFyZ2MsIGNoYXIqKiBhcmd2KSB7CiAgcmNsY3BwOjppbml0KGFyZ2MsIGFyZ3YpOwogIHJjbGNwcDo6c3BpbihzdGQ6Om1ha2Vfc2hhcmVkPF9fUExVR0lOX0NMQVNTX19Ob2RlPigpKTsKICByY2xjcHA6OnNodXRkb3duKCk7CiAgcmV0dXJuIDA7Cn0KYGBgCgpgUkJQbHVnaW5DYWxsYCBhbmQgYFBsdWdpblByb2dyYW1Db250ZXh0YCB3b3JrIGluIGFuIHJjbGNwcCBub2RlIHRvbyDigJQgY3JlYXRlCnRoZW0gaW4gYG1haW4oKWAgYmVmb3JlIGByY2xjcHA6OnNwaW5gLgoKCiMjIyMgVGFsa2luZyB0byBhbiBleHRlcm5hbCBQQyBvdmVyIFJPUyAyCgpST1MgMiBkaXNjb3Zlcnkgc3RheXMgb24gdGhlIHJvYm90IChgUk9TX0FVVE9NQVRJQ19ESVNDT1ZFUllfUkFOR0U9TE9DQUxIT1NUYDsgYG11c2NhdC1wayBkZXZgCnJ1bnMgdGhlIHNhbWUpLCBzbyByb2JvdHMgb24gb25lIExBTiBkb24ndCBtaXggdG9waWNzLiBBbGxvdyBzcGVjaWZpYyBQQ3MgZnJvbSB0aGUgcGx1Z2luIFVJIOKAlApNdXNjYXQga2VlcHMgdGhlIGxpc3QgcGVyIHBsdWdpbiwgc3RhcnRzIHlvdXIgYmFja2VuZCB3aXRoIGBST1NfU1RBVElDX1BFRVJTYCBzZXQgdG8gaXQsIGFuZApyZXN0YXJ0cyB0aGUgcGx1Z2luIHdoZW4gaXQgY2hhbmdlcy4gWW91ciBST1MgY29kZSBuZWVkcyBubyBjaGFuZ2VzOyB0aGUgUEMgbmVlZHMgbm8gZXh0cmEgc2V0dGluZ3MuCgpgYGB0c3gKY29uc3QgcmIgPSB1c2VSYigpOwpjb25zdCBwZWVycyA9IGF3YWl0IHJiLnJvc1BlZXJzLmdldCgpOyAgICAgICAgICAgICAgIC8vIFsiMTkyLjE2OC4wLjUwIl0KYXdhaXQgcmIucm9zUGVlcnMuc2V0KFsiMTkyLjE2OC4wLjUwIiwgIjE5Mi4xNjguMC41MSJdKTsgLy8gc2F2ZXMgKyByZXN0YXJ0cyB0aGUgcGx1Z2luOyByZWplY3RzIG9uIGEgYmFkIElQCmBgYAoKLSBQZXIgcGx1Z2luOiBwbHVnaW4gQiBrZWVwcyBpdHMgYWxsb3dlZCBQQ3Mgd2hlbiBwbHVnaW4gQSAoYWxsb3dpbmcgdGhlIHNhbWUgUEMpIGlzIHN0b3BwZWQgb3IgcmVtb3ZlZC4KLSBJdCBvcGVucyBjb21tdW5pY2F0aW9uOyBpdCBpcyBub3QgYWNjZXNzIGNvbnRyb2wg4oCUIGEgUEMgdGhhdCBrbm93cyB0aGUgcm9ib3QncyBJUCBjYW4gc3RpbGwKICBhZGQgdGhlIHJvYm90IHRvIGl0cyBvd24gYFJPU19TVEFUSUNfUEVFUlNgLgotIEluIGBtdXNjYXQtcGsgZGV2YCB0aGUgbGlzdCBpcyBrZXB0IGluIGAubXVzY2F0LWRldi9yb3MtcGVlcnMuanNvbmAgKFJPUyAyIGJhY2tlbmRzKS4KCi0tLQoKIyMgVmlkZW8gc3RyZWFtaW5nIChNZWRpYU1UWCkKCk11c2NhdCBydW5zIGEgTWVkaWFNVFggbWVkaWEgc2VydmVyLiBUaGUgYmFja2VuZCBwdWJsaXNoZXMgYSBzdHJlYW0gb3ZlciBSVFNQIGFuZAp0aGUgVUkgcGxheXMgaXQgb3ZlciBXZWJSVEMuIGBtdXNjYXQtcGsgZGV2YCBydW5zIHRoZSBzYW1lIHNlcnZlciAob3IgdXNlcyBhIGxvY2FsCk11c2NhdCdzKSwgc28gdGhlIGFkZHJlc3NlcyBhcmUgaWRlbnRpY2FsIGluIGRldiBhbmQgb24gdGhlIHJvYm90LgoKfCB8IEFkZHJlc3MgfAp8IC0tLSB8IC0tLSB8CnwgUHVibGlzaCAoYmFja2VuZCkgfCBgcnRzcDovLzEyNy4wLjAuMTo4NTU0LzxwbHVnaW5faWQ+LzxuYW1lPmAgfAp8IFBsYXkgKFVJKSB8IGBodHRwOi8vPGhvc3Q+Ojg4ODkvPHBsdWdpbl9pZD4vPG5hbWU+L2AgfAoKLSBQcmVmaXggdGhlIHBhdGggd2l0aCB5b3VyIHBsdWdpbiBpZCDigJQgcGF0aHMgYXJlIHNoYXJlZCB3aXRoIHJvYm90IGNhbWVyYXMgYW5kIG90aGVyIHBsdWdpbnMuCi0gVGhlIHJvYm90IHJ1bnRpbWUgaGFzIG5vIGZmbXBlZywgR1N0cmVhbWVyIG9yIE9wZW5DVjsgYnJpbmcgeW91ciBvd24gZW5jb2RlciAoYmVsb3cpLgoKKipCYWNrZW5kIChDKyspKiog4oCUIHB1Ymxpc2ggUlRTUCB3aXRoIGFuIGVuY29kZXIgbGlicmFyeSB5b3UgYnJpbmcgKGUuZy4gRkZtcGVnJ3MKbGliYXZmb3JtYXQgLyBsaWJ4MjY0KTsgdGhlIHJvYm90IGhhcyBub25lIGluc3RhbGxlZC4gU2hpcCBpdCB3aXRoIHRoZSBwbHVnaW4g4oCUIHNlZQpfQnVuZGxpbmcgZXh0cmEgc2hhcmVkIGxpYnJhcmllc18uCgoqKlVJKiog4oCUIGVtYmVkIE1lZGlhTVRYJ3MgV2ViUlRDIHBsYXllci4gYGxvY2F0aW9uLmhvc3RuYW1lYCBpcyBgbG9jYWxob3N0YCBpbiB0aGUKcHJldmlldyBhbmQgdGhlIHJvYm90J3MgYWRkcmVzcyBvbiB0aGUgcm9ib3Q6CgpgYGB0c3gKY29uc3QgU1RSRUFNID0gIl9fUExVR0lOX0lEX18vY2FtIjsgLy8gdGhlIHBhdGggdGhlIGJhY2tlbmQgcHVibGlzaGVzCgpleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBDYW1lcmEoKSB7CiAgcmV0dXJuICgKICAgIDxpZnJhbWUKICAgICAgc3JjPXtgJHtsb2NhdGlvbi5wcm90b2NvbH0vLyR7bG9jYXRpb24uaG9zdG5hbWV9Ojg4ODkvJHtTVFJFQU19L2B9CiAgICAgIGFsbG93PSJhdXRvcGxheSIKICAgICAgY2xhc3NOYW1lPSJhc3BlY3QtdmlkZW8gdy1mdWxsIGJvcmRlci0wIgogICAgLz4KICApOwp9CmBgYAoKLS0tCgojIyBtYW5pZmVzdC5qc29uCgpgYGBqc29uYwp7CiAgLy8gdW5pcXVlIHBsdWdpbiBJRCDigJQgcmV2ZXJzZS1kb21haW4gZm9ybWF0IHJlY29tbWVuZGVkCiAgImlkIjogImNvbS5leGFtcGxlLm15LXBsdWdpbiIsCiAgIm5hbWUiOiAiTXkgUGx1Z2luIiwKICAidmVyc2lvbiI6ICIxLjAuMCIsCgogIC8vIG1pbmltdW0gTXVzY2F0IHZlcnNpb24gcmVxdWlyZWQgdG8gbG9hZCB0aGlzIHBsdWdpbgogICJtaW5NdXNjYXRWZXJzaW9uIjogIjEuMC4wIiwKCiAgLy8gcGx1Z2luIGF1dGhvciAoZW1wdHkgc3RyaW5nIGlzIGZpbmUpCiAgImF1dGhvciI6ICJZb3VyIE5hbWUiLAoKICAvLyBkaXNwbGF5ZWQgaW4gdGhlIE11c2NhdCBwbHVnaW4gc3RvcmUgLyBpbmZvIHBhbmVsCiAgLy8gc3RyaW5nIG9yIHsgZW4gKHJlcXVpcmVkKSwga28sIGphLCB6aCwgdmksIHRoLCBlcyB9CiAgImRlc2NyaXB0aW9uIjogeyAiZW4iOiAiUGx1Z2luIGRlc2NyaXB0aW9uIiwgImtvIjogIu2UjOufrOq3uOyduCDshKTrqoUiIH0sCgogIC8vIFNWRyBzdHJpbmcgKHNpbmdsZSBmaWxlKSBvciBQTkcvSlBHIHNpemUgbWFwIChhbGwgdGhyZWUgc2l6ZXMgcmVxdWlyZWQpCiAgImljb25zIjogImFzc2V0cy9pY29uLnN2ZyIsCiAgLy8gImljb25zIjogeyAiMTYiOiAiYXNzZXRzL2ljb24tMTYucG5nIiwgIjQ4IjogImFzc2V0cy9pY29uLTQ4LnBuZyIsICIxMjgiOiAiYXNzZXRzL2ljb24tMTI4LnBuZyIgfSwKCiAgLy8gdGFyZ2V0TW9kZWxzIGFuZC9vciB0YXJnZXRDYXRlZ29yeXMg4oCUIGF0IGxlYXN0IG9uZSBpcyByZXF1aXJlZAogIC8vICJhbGwiID0gZXZlcnkgdGFyZ2V0LCBvciBsaXN0IHNwZWNpZmljIHZhbHVlcwogICJ0YXJnZXRNb2RlbHMiOiAiYWxsIiwKICAvLyAidGFyZ2V0TW9kZWxzIjogWyJDNTAwOTIwIiwgIkM1MDA5MzAiXSwKICAidGFyZ2V0Q2F0ZWdvcnlzIjogImFsbCIsCiAgLy8gInRhcmdldENhdGVnb3J5cyI6IFsibWFuaXB1bGF0ZSIsICJhbXIiLCAicmJ5MSIsICJ2aXNpb24iXSwKCiAgImNvbnRyaWJ1dGVzIjogWwogICAgLy8gcHJvZ3JhbS5wYW5lbCDigJQgZGVmaW5lcyBhIGN1c3RvbSBjb21tYW5kIGZvciB0aGUgUHJvZ3JhbSBwYWdlIHNlcXVlbmNlCiAgICAvLyAgIGJ1aWxkZXI7IHJ1bnMgdmlhIFBsdWdpblByb2dyYW1Db250ZXh0IHdoZW4gdGhlIHByb2dyYW0gcmVhY2hlcyBpdAogICAgewogICAgICAicG9pbnQiOiAicHJvZ3JhbS5wYW5lbCIsCiAgICAgICJpY29uIjogImFzc2V0cy9pY29uLnN2ZyIsCiAgICAgICJsYWJlbCI6IHsgImtvIjogIuuCtCDtlIzrn6zqt7jsnbgiLCAiZW4iOiAiTXkgUGx1Z2luIiB9LAogICAgICAidWkiOiAicHJvZ3JhbSIsICAgICAgICAgICAvLyBtdXN0IGJlIHVuaXF1ZSBhY3Jvc3MgYWxsIGNvbnRyaWJ1dGlvbnMKICAgICAgImNvbW1hbmRJbmZvIjogewogICAgICAgICJuYW1lIjogIk15IFBsdWdpbiIsCiAgICAgICAgImljb24iOiAiYXNzZXRzL2ljb24uc3ZnIiwKICAgICAgICAiZnVuY05hbWUiOiAicmJfcHJvZ3JhbV9zZGsucGx1Z2luX2V4ZWN1dGUiLAogICAgICAgICJhcmdzIjoge30KICAgICAgfQogICAgfSwKICAgIC8vIHRvb2xiYXIg4oCUIGFkZHMgYSBidXR0b24gdG8gdGhlIHRvcCB0b29sYmFyIChyZXF1aXJlZCkKICAgIHsKICAgICAgInBvaW50IjogInRvb2xiYXIiLAogICAgICAiaWNvbiI6ICJhc3NldHMvaWNvbi5zdmciLAogICAgICAibGFiZWwiOiB7ICJrbyI6ICLrgrQg7ZSM65+s6re47J24IiwgImVuIjogIk15IFBsdWdpbiIgfSwKICAgICAgInVpIjogImNvbnRlbnQiLCAgICAgICAgICAgLy8gbXVzdCBiZSB1bmlxdWUgYWNyb3NzIGFsbCBjb250cmlidXRpb25zCiAgICAgICJvcGVucyI6ICJwb3BvdmVyIiAgICAgICAgIC8vIHBvcG92ZXIgfCBwYW5lbCB8IHBhZ2UKICAgIH0sCiAgICAvLyBtb3ZlLnBhbmVsIOKAlCBhZGRzIGEgcGFuZWwgdG8gdGhlIE1vdmUgc2NyZWVuCiAgICB7CiAgICAgICJwb2ludCI6ICJtb3ZlLnBhbmVsIiwKICAgICAgImljb24iOiAiYXNzZXRzL2ljb24uc3ZnIiwKICAgICAgImxhYmVsIjogeyAia28iOiAi64K0IO2UjOufrOq3uOyduCIsICJlbiI6ICJNeSBQbHVnaW4iIH0sCiAgICAgICJ1aSI6ICJtb3ZlIiAgICAgICAgICAgICAgIC8vIG11c3QgYmUgdW5pcXVlIGFjcm9zcyBhbGwgY29udHJpYnV0aW9ucwogICAgfQogIF0sCgogIC8vIG9wdGlvbmFsOiB2YXJpYWJsZXMgdGhpcyBwbHVnaW4gZXhwb3NlcyB0byBweWZtIHByb2dyYW1zIOKAlCB0aGUgUHJvZ3JhbQogIC8vIHBhZ2UgdmFyaWFibGUgcGlja2VyIGxpc3RzIE9OTFkgZGVjbGFyZWQgdmFyaWFibGVzLiBuYW1lIG11c3Qgc3RhcnQgd2l0aAogIC8vIFJCUF87IGRlc2NyaXB0aW9uIGlzIG9wdGlvbmFsIGJ1dCB3aXRob3V0IGl0IHRoZSBVSSBjYW4ndCBleHBsYWluIHRoZQogIC8vIHZhcmlhYmxlLCBzbyB3cml0ZSBvbmUuCiAgInZhcmlhYmxlcyI6IFsKICAgIHsgIm5hbWUiOiAiUkJQX2dyaXBfZm9yY2UiLCAidHlwZSI6ICJudW1iZXIiLCAiaW5pdCI6IDAuNSwgImRlc2NyaXB0aW9uIjogeyAia28iOiAi6re466as7Y28IO2emCIsICJlbiI6ICJHcmlwcGVyIGZvcmNlIiB9IH0sCiAgICB7ICJuYW1lIjogIlJCUF90YXJnZXRfcG9zZSIsICJ0eXBlIjogImFycmF5IiwgImluaXQiOiBbMCwgMCwgMF0gfQogIF0sCgogIC8vIHJ1bnRpbWUg4oCUIG9uZSBvZjoKICAvLyAgIHsgInR5cGUiOiAibm9uZSIgfQogIC8vICAgeyAidHlwZSI6ICJweXRob24iLCAiZW50cnkiOiAibWFpbi5weSIgfQogIC8vICAgeyAidHlwZSI6ICJjcHAiLCAiZW50cnkiOiAiPGV4ZWN1dGFibGUgbmFtZT4iIH0KICAvLyAgIHsgInR5cGUiOiAicm9zMiIsICJyb3NDbGllbnQiOiAicmNscHkiIHwgInJjbGNwcCIsICJwYWNrYWdlIjogIi4uLiIsICJsYXVuY2giOiAiLi4uX25vZGUiIH0KICAicnVudGltZSI6IHsgInR5cGUiOiAiY3BwIiwgImVudHJ5IjogIl9fUExVR0lOX1NMVUdfXyIgfSwKCiAgLy8gb3B0aW9uYWw6IFRDUCBwb3J0cyBvcGVuZWQgYnkgdGhpcyBwbHVnaW4gYmFja2VuZAogIC8vIG9ubHkgbnVtYmVyW10gaXMgYWxsb3dlZDsgcmFuZ2VzL29iamVjdHMgYXJlIG5vdCBhY2NlcHRlZAogIC8vIGV4dGVybmFsIHBsdWdpbiBwb3J0cyBtdXN0IGJlIHdpdGhpbiAyODYwMC0yODk5OQogICJwb3J0cyI6IFsyODYwMF0KfQpgYGAKCioqQmFja2VuZCB0eXBlczoqKgoKfCB0eXBlIHwgc291cmNlIGRpciB8IGJ1aWxkIC8gcnVuIHwgZW50cnkgfAp8LS0tfC0tLXwtLS18LS0tfAp8IGBweXRob25gIHwgYHB5L2AgfCBwaXAgKyBydW4gaW4gRG9ja2VyIHwgYG1haW4ucHlgIHwKfCBgY3BwYCB8IGBjcHAvYCB8IENNYWtlIGluIERvY2tlciB8IGJ1aWx0IGV4ZWN1dGFibGUgbmFtZSB8CnwgYHJvczJgIChyY2xweSkgfCBgcm9zMl93cy9gIHwgY29sY29uIChhbWVudF9weXRob24pIGluIERvY2tlciB8IOKAlCB8CnwgYHJvczJgIChyY2xjcHApIHwgYHJvczJfd3MvYCB8IGNvbGNvbiAoYW1lbnRfY21ha2UpIGluIERvY2tlciB8IOKAlCB8Cgo+IEV2ZXJ5IGJhY2sgZW5kIHJ1bnMgaW4gYSBEb2NrZXIgY29udGFpbmVyIG1hdGNoaW5nIHRoZSByb2JvdCAoVWJ1bnR1IDI0LjA0ICsgUHl0aG9uIDMuMTIpLCBzbyBkZXYgYmVoYXZlcyBsaWtlIHByb2R1Y3Rpb24gYW5kIGNvbXBpbGVkIGJpbmFyaWVzIGFyZSBBQkktY29tcGF0aWJsZS4gKipEb2NrZXIgaXMgcmVxdWlyZWQqKiBmb3IgYWxsIGJhY2tlbmQgdHlwZXMgKG9ubHkgYSBmcm9udGVuZC1vbmx5IGBub25lYCBwbHVnaW4gc2tpcHMgaXQpLiBObyBsb2NhbCBQeXRob24vdG9vbGNoYWluIHNldHVwIGlzIG5lZWRlZC4KCioqQ29udHJpYnV0aW9uIHBvaW50czoqKgoKfCBwb2ludCB8IFdoZXJlIGl0IGFwcGVhcnMgfCBCYWNrZW5kIHwgYGNvbW1hbmRJbmZvYCB8CnwtLS18LS0tfC0tLXw6LS0tOnwKfCBgdG9vbGJhcmAgfCBUb3AgdG9vbGJhciBidXR0b24gKG11c3QgaGF2ZSBhdCBsZWFzdCBvbmUpIHwgU0RLIC8gYHJiLmFjdGlvbmAgfCDigJQgfAp8IGBsbmJgIHwgTGVmdCBuYXZpZ2F0aW9uIGVudHJ5IHwgU0RLIC8gYHJiLmFjdGlvbmAgfCDigJQgfAp8IGBtb3ZlLnBhbmVsYCB8IE1vdmUgc2NyZWVuIHBhbmVsIHwgU0RLIC8gYHJiLmFjdGlvbmAgfCDigJQgfAp8IGBwcm9ncmFtLnBhbmVsYCB8IEN1c3RvbSBjb21tYW5kIGluIHRoZSBQcm9ncmFtIHBhZ2Ugc2VxdWVuY2UgYnVpbGRlciB8IGBQbHVnaW5Qcm9ncmFtQ29udGV4dGAgfCDinJMgfAoKKipgY29tbWFuZEluZm9gIGZpZWxkcyoqIChmb3IgYHByb2dyYW0ucGFuZWxgKToKCnwgZmllbGQgfCB0eXBlIHwgZGVzY3JpcHRpb24gfAp8LS0tfC0tLXwtLS18CnwgYG5hbWVgIHwgYHN0cmluZ2AgfCBEaXNwbGF5IG5hbWUgb2YgdGhlIGNvbW1hbmQgaW4gdGhlIHByb2dyYW0gdHJlZSB8CnwgYGljb25gIHwgYHN0cmluZ2AgfCBJY29uIHBhdGggfAp8IGBpY29uQ2xhc3NOYW1lYCB8IGBzdHJpbmc/YCB8IE9wdGlvbmFsIENTUyBjbGFzcyBmb3IgdGhlIGljb24gfAp8IGBmdW5jTmFtZWAgfCBgc3RyaW5nP2AgfCBCYWNrZW5kIGZ1bmN0aW9uIG5hbWUgdG8gY2FsbCB8CnwgYGFyZ3NgIHwgYFJlY29yZDxzdHJpbmcsIGFueT4/YCB8IERlZmF1bHQgYXJndW1lbnRzIHwKfCBgZGlzYWJsZWRgIHwgYGJvb2xlYW4/YCB8IFdoZXRoZXIgdGhlIG5vZGUgaXMgZGlzYWJsZWQgfAp8IGBhbGxvd0NoaWxkcmVuYCB8IGBzdHJpbmdbXT9gIHwgQWxsb3dlZCBjaGlsZCBjb21tYW5kcyB8CnwgYGFsbG93UGFyZW50c2AgfCBgc3RyaW5nW10/YCB8IEFsbG93ZWQgcGFyZW50IGNvbW1hbmRzIHwKfCBgbm90QWxsb3dDaGlsZHJlbmAgfCBgc3RyaW5nW10/YCB8IERpc2FsbG93ZWQgY2hpbGQgY29tbWFuZHMgfAp8IGBzeW5jR3JvdXBJZGAgfCBgYm9vbGVhbj9gIHwgU3luYyBncm91cCBJRCBhY3Jvc3MgY2hpbGRyZW4gfAp8IGBkaXNhYmxlQ29weWAgfCBgYm9vbGVhbj9gIHwgUHJldmVudCBjb3B5IHwKfCBgZGlzYWJsZURlbGV0ZWAgfCBgYm9vbGVhbj9gIHwgUHJldmVudCBkZWxldGUgfAp8IGByZXF1aXJlQ2hpbGRyZW5gIHwgYGJvb2xlYW4/YCB8IFdoZXRoZXIgYSBjaGlsZCBjb21tYW5kIGlzIHJlcXVpcmVkIHwKfCBgcmVxdWlyZVBhcmVudGAgfCBgYm9vbGVhbj9gIHwgV2hldGhlciBhIHBhcmVudCBjb21tYW5kIGlzIHJlcXVpcmVkIHwKfCBgY2hpbGRyZW5Db21tYW5kYCB8IGBzdHJpbmc/YCB8IERlZmF1bHQgY29tbWFuZCB0eXBlIGZvciBjaGlsZHJlbiB8CgoqKlZhbGlkYXRpb24gcnVsZXM6KioKLSBgaWRgLCBgbmFtZWAsIGB2ZXJzaW9uYCwgYG1pbk11c2NhdFZlcnNpb25gIOKAlCByZXF1aXJlZCBub24tZW1wdHkgc3RyaW5ncwotIGBhdXRob3JgIOKAlCByZXF1aXJlZCBub24tZW1wdHkgc3RyaW5nCi0gYGRlc2NyaXB0aW9uYCDigJQgcmVxdWlyZWQgKGBzdHJpbmdgIG9yIGB7IGVuIChyZXF1aXJlZCksIGtvPywgamE/LCB6aD8sIHZpPywgdGg/LCBlcz8gfWApCi0gYGljb25zYCDigJQgU1ZHOiBzaW5nbGUgc3RyaW5nIHBhdGggZW5kaW5nIGluIGAuc3ZnYDsgUE5HL0pQRzogb2JqZWN0IHdpdGggYCIxNiJgLCBgIjQ4ImAsIGAiMTI4ImAgYWxsIHByZXNlbnQKLSBgdGFyZ2V0TW9kZWxzYCDigJQgYCJhbGwiYCBvciBhIG5vbi1lbXB0eSBhcnJheSBvZiByb2JvdCBtb2RlbCBJRCBzdHJpbmdzIChhdCBsZWFzdCBvbmUgb2YgYHRhcmdldE1vZGVsc2AgLyBgdGFyZ2V0Q2F0ZWdvcnlzYCByZXF1aXJlZCkKLSBgdGFyZ2V0Q2F0ZWdvcnlzYCDigJQgYCJhbGwiYCBvciBhIG5vbi1lbXB0eSBhcnJheSBvZiBgIm1hbmlwdWxhdGUiIHwgImFtciIgfCAicmJ5MSIgfCAidmlzaW9uImAgKGF0IGxlYXN0IG9uZSBvZiBgdGFyZ2V0TW9kZWxzYCAvIGB0YXJnZXRDYXRlZ29yeXNgIHJlcXVpcmVkKQotIGBjb250cmlidXRlc2Ag4oCUIHRoZSBwbHVnaW4ncyBzY3JlZW5zOyB3aGVuIHByZXNlbnQgaXQgbXVzdCBjb250YWluIGF0IGxlYXN0IG9uZSBgdG9vbGJhcmAgZW50cnkuIExlYXZlIGl0IG91dCAob3IgYFtdYCkgZm9yIGEgYmFja2VuZC1vbmx5IHBsdWdpbjogbm8gVUkgaXMgYnVpbHQsIGFuZCBOb2RlLmpzIGlzIG5vdCBuZWVkZWQgdG8gYnVpbGQgaXQKLSBgdWlgIOKAlCBlYWNoIGNvbnRyaWJ1dGlvbiBtdXN0IGhhdmUgYSB1bmlxdWUgdmFsdWUKLSBgY29tbWFuZEluZm9gIOKAlCByZXF1aXJlZCB3aGVuIGBwb2ludGAgaXMgYCJwcm9ncmFtLnBhbmVsImAKLSBgcG9ydHNgIOKAlCBvcHRpb25hbCBgbnVtYmVyW11gOyBldmVyeSBwb3J0IG11c3QgYmUgd2l0aGluIGAyODYwMC0yODk5OWAKICBhbmQgbXVzdCBub3QgYmUgYSByZXNlcnZlZCByb2JvdC9pbmR1c3RyaWFsL2ludGVybmFsIHBvcnQKLSBgdmFyaWFibGVzYCDigJQgb3B0aW9uYWwgYXJyYXkgb2YgYHsgbmFtZSwgdHlwZSwgaW5pdCwgZGVzY3JpcHRpb24/IH1gOgogIC0gYG5hbWVgIOKAlCBtdXN0IHN0YXJ0IHdpdGggYFJCUF9gLCB0aGVuIGxldHRlcnMvZGlnaXRzL3VuZGVyc2NvcmU7IHVuaXF1ZSBwZXIgcGx1Z2luCiAgLSBgdHlwZWAg4oCUIGAibnVtYmVyIiB8ICJzdHJpbmciIHwgImFycmF5ImAKICAtIGBpbml0YCDigJQgcmVxdWlyZWQgaW5pdGlhbCB2YWx1ZSwgbXVzdCBtYXRjaCBgdHlwZWAKICAtIGBkZXNjcmlwdGlvbmAg4oCUIG9wdGlvbmFsIGBzdHJpbmdgIG9yIGkxOG4gb2JqZWN0IChgZW5gIHJlcXVpcmVkIGluIG9iamVjdCBmb3JtKQoKYG11c2NhdC1wayBidWlsZGAgdGhyb3dzIG9uIGFueSB2YWxpZGF0aW9uIGVycm9yLiBgbXVzY2F0LXBrIGRldmAgcHJpbnRzCndhcm5pbmdzIOKAlCBleGNlcHQgYHZhcmlhYmxlc2AgZXJyb3JzIChlLmcuIGEgbmFtZSB3aXRob3V0IHRoZSBgUkJQX2AgcHJlZml4KSwKd2hpY2ggYXJlIGhhcmQgZXJyb3JzIGluIGBkZXZgIC8gYGRldjpiYWNrYCB0b28uCgoqKkJhY2tlbmQgcG9ydCBydWxlczoqKgotIERlY2xhcmUgYSBwb3J0IG9ubHkgaWYgeW91ciBiYWNrZW5kIG9wZW5zIGEgVENQIHNlcnZlci9saXN0ZW5lci4KLSAqKkV2ZXJ5IGxpc3RlbmluZyBUQ1AgcG9ydCBtdXN0IGJlIGRlY2xhcmVkLioqIGBtdXNjYXQtcGsgZGV2YCBhbmQKICBgbXVzY2F0LXBrIGRldjpiYWNrYCB3YXRjaCB0aGUgYmFja2VuZCBhbmQgc3RvcCBpdCB0aGUgbW9tZW50IGl0IG9wZW5zIGEgcG9ydAogIHRoYXQgaXMgbm90IGluIGBwb3J0c2AuIEEgcG9ydCBvdXRzaWRlIGAyODYwMC0yODk5OWAgY2FuJ3QgYmUgZGVjbGFyZWQsIHNvIGl0CiAgbXVzdCBub3QgYmUgb3BlbmVkIGVpdGhlciDigJQgcGlja2luZyBlLmcuIGA1NTAwYCBpcyBub3QgYSB3YXkgYXJvdW5kIHRoZSBydWxlLgogIEl0IHdvdWxkIGVzY2FwZSB0aGlzIGNoZWNrICphbmQqIHRoZSByb2JvdCdzIGluc3RhbGwtdGltZSBjb25mbGljdCBjaGVjaywgYW5kCiAgb25seSBjb2xsaWRlIG9uY2UgaXQncyBydW5uaW5nIG9uIGEgcm9ib3QuCi0gUmVzZXJ2ZWQgcG9ydHMgaW5jbHVkZSBgNTAyYCwgYDIyMjJgLCBgNDg0MGAsIGA1MTcwLTUxNzlgLCBgODAwMC04OTk5YCwKICBgMTAwMDBgLCBgMzAwMDRgLCBgMzQ5NjRgLCBgNDQ4MThgLCBgNTAwMDAtNTAwMDVgLCBhbmQgYDUwMDUxYC4KLSBUaGUgcm9ib3QgcmVqZWN0cyBpbnN0YWxsYXRpb24gKEhUVFAgNDA5KSBpZiBhIGRlY2xhcmVkIHBvcnQgaXMgcmVzZXJ2ZWQsCiAgb3V0IG9mIHJhbmdlLCBvciBhbHJlYWR5IGNsYWltZWQgYnkgYW5vdGhlciBlbmFibGVkIHBsdWdpbi4KCioqUmVhY2hpbmcgeW91ciBiYWNrZW5kJ3MgcG9ydHMgZHVyaW5nIGRldmVsb3BtZW50OioqCi0gRGVjbGFyZWQgcG9ydHMgYXJlIHB1Ymxpc2hlZCB0byBgMTI3LjAuMC4xYCBvbiB5b3VyIG1hY2hpbmUsIHNvCiAgYGN1cmwgaHR0cDovLzEyNy4wLjAuMToyODYwMGAgd29ya3MgZnJvbSB0aGUgaG9zdCBvbiBtYWNPUywgV2luZG93cywgYW5kIExpbnV4LgotIE9uIG5hdGl2ZSBMaW51eCB0aGUgZGV2IGNvbnRhaW5lciB1c2VzIGhvc3QgbmV0d29ya2luZywgc28gdGhlIHBvcnRzIGFyZSBvbgogIHRoZSBob3N0IGFscmVhZHkuCi0gSWYgYSBkZWNsYXJlZCBwb3J0IGlzIGFscmVhZHkgdGFrZW4gb24geW91ciBtYWNoaW5lLCBgbXVzY2F0LXBrIGRldmAgd2FybnMgYW5kCiAgc2tpcHMgcHVibGlzaGluZyB0aGF0IG9uZSDigJQgdGhlIGJhY2tlbmQgc3RpbGwgbGlzdGVucyBpbnNpZGUgdGhlIGNvbnRhaW5lci4KCi0tLQoKIyMgTG9jYWxpemVkIGRvY3VtZW50YXRpb24KCllvdSBjYW4gc2hpcCBwZXItbGFuZ3VhZ2UgUkVBRE1FIGZpbGVzIGFsb25nc2lkZSB0aGUgbWFpbiBgUkVBRE1FLm1kYC4gUGxhY2UgdGhlbSBpbiB0aGUgcHJvamVjdCByb290OgoKYGBgClJFQURNRS5tZCAgICAgICAgIyBkZWZhdWx0IC8gRW5nbGlzaCBmYWxsYmFjawpSRUFETUUua28ubWQgICAgICMgS29yZWFuClJFQURNRS5lbi5tZCAgICAgIyBleHBsaWNpdCBFbmdsaXNoIChvcHRpb25hbCkKUkVBRE1FLmphLm1kICAgICAjIEphcGFuZXNlCmBgYAoKQWxsIGBSRUFETUUqLm1kYCBmaWxlcyBmb3VuZCBhdCB0aGUgcHJvamVjdCByb290IGFyZSBhdXRvbWF0aWNhbGx5IGNvcGllZCB0byBgZGlzdC9gIG9uCmBtdXNjYXQtcGsgYnVpbGRgLiBNdXNjYXQgZGlzcGxheXMgdGhlIGZpbGUgbWF0Y2hpbmcgdGhlIHVzZXIncyBsb2NhbGUsCmZhbGxpbmcgYmFjayB0byBgUkVBRE1FLm1kYCBpZiBub25lIG1hdGNoZXMuCgotLS0KCiMjIEMrKyBTREsgJiBkZXBlbmRlbmNpZXMKClRoZSBkZXYgY29udGFpbmVyIGhhcyB0aGUgQysrIFNESyAoYHJhaW5ib3ctcmItc2RrLWRldmApIHByZS1pbnN0YWxsZWQg4oCUIG5vIGxvY2FsCmluc3RhbGwgbmVlZGVkLiBUaGUgU0RLIHZlcnNpb24gaXMgdGhlIG9uZSBwaW5uZWQgaW4gYENNYWtlTGlzdHMudHh0YCAoYGZpbmRfcGFja2FnZShyYl9zZGsgPHZlcnNpb24+IEVYQUNUIFJFUVVJUkVEKWApLiBQaWNrIGEgZGlmZmVyZW50IG9uZSB3aXRoOgoKYGBgYmFzaAptdXNjYXQtcGsgc2RrIHVwZGF0ZSA8dmVyc2lvbj4KYGBgCgpgbXVzY2F0LXBrIGJ1aWxkYCBjb3BpZXMgdGhlIG1hdGNoaW5nIGBsaWJyYl9zZGsuc29gIG5leHQgdG8geW91ciBiaW5hcnkKKGBkaXN0LzxhcmNoPi9saWIvYCwgb3IgYGluc3RhbGwtPGFyY2g+Lzxwa2c+L2xpYi9gIGZvciByY2xjcHApLCBzbyB0aGUgcm9ib3QgbmVlZHMgbm8gU0RLCmluc3RhbGwgYW5kIGVhY2ggcGx1Z2luIGtlZXBzIHRoZSBTREsgdmVyc2lvbiBpdCB3YXMgYnVpbHQgd2l0aC4KCk90aGVyIGxpYnJhcmllczogaW5zdGFsbCB0aGVtIGluIHRoZSBidWlsZCAoZS5nLiB2ZW5kb3IgdGhlbSB1bmRlciBgY3BwL2AgYW5kCmBhZGRfc3ViZGlyZWN0b3J5YCwgb3IgbGluayBzdGF0aWNhbGx5KSDigJQgdGhlIHJvYm90IG9ubHkgaGFzIFVidW50dSAyNC4wNCBiYXNlCmxpYnJhcmllcy4KClRvIHVzZSB0aGUgU0RLIG91dHNpZGUgYSBwbHVnaW4gKHlvdXIgb3duIFVidW50dSAyNC4wNCBtYWNoaW5lKToKCmBgYGJhc2gKY3VybCAtZnNTTCBodHRwczovL3JhaW5ib3dyb2JvdGljcy5naXRodWIuaW8vcmItc2RrL3JiLXNkay1hcHQtcmVwby5ncGcua2V5IHwgc3VkbyBncGcgLS1kZWFybW9yIC1vIC91c3Ivc2hhcmUva2V5cmluZ3MvcmItc2RrLWFwdC5ncGcKZWNobyAnZGViIFtzaWduZWQtYnk9L3Vzci9zaGFyZS9rZXlyaW5ncy9yYi1zZGstYXB0LmdwZ10gaHR0cHM6Ly9yYWluYm93cm9ib3RpY3MuZ2l0aHViLmlvL3JiLXNkayBzdGFibGUgbWFpbicgfCBzdWRvIHRlZSAvZXRjL2FwdC9zb3VyY2VzLmxpc3QuZC9yYi1zZGsubGlzdApzdWRvIGFwdCB1cGRhdGUgJiYgc3VkbyBhcHQgaW5zdGFsbCByYWluYm93LXJiLXNkay1kZXYKYGBgCgoKIyMjIEJ1bmRsaW5nIGV4dHJhIHNoYXJlZCBsaWJyYXJpZXMKClRoZSByb2JvdCBvbmx5IGhhcyBVYnVudHUgMjQuMDQgYmFzZSBsaWJyYXJpZXMuIENvcHkgYW55IG90aGVyIGAuc29gIHlvdXIgZXhlY3V0YWJsZQpuZWVkcyBpbnRvIGAke0NNQUtFX0JJTkFSWV9ESVJ9L2xpYmAg4oCUIGBtdXNjYXQtcGsgYnVpbGRgIHNoaXBzIHRoYXQgZm9sZGVyIGFzCmBkaXN0LzxhcmNoPi9saWIvYCBhbmQgdGhlIGV4ZWN1dGFibGUgZmluZHMgaXQgdmlhIGl0cyBSUEFUSCAoYCRPUklHSU4vbGliYCk6CgpgYGBjbWFrZQojIGNwcC9DTWFrZUxpc3RzLnR4dCDigJQgdGhpcmRfcGFydHkvIGhvbGRzIHByZWJ1aWx0IGxpYnMgZm9yIGFtZDY0IC8gYXJtNjQKc2V0KEFSQ0hfRElSICR7Q01BS0VfU09VUkNFX0RJUn0vdGhpcmRfcGFydHkvJHtDTUFLRV9TWVNURU1fUFJPQ0VTU09SfSkKdGFyZ2V0X2xpbmtfbGlicmFyaWVzKF9fUExVR0lOX1NMVUdfXyBQUklWQVRFICR7QVJDSF9ESVJ9L2xpYmZvby5zbykKYWRkX2N1c3RvbV9jb21tYW5kKFRBUkdFVCBfX1BMVUdJTl9TTFVHX18gUE9TVF9CVUlMRAogIENPTU1BTkQgJHtDTUFLRV9DT01NQU5EfSAtRSBtYWtlX2RpcmVjdG9yeSAke0NNQUtFX0JJTkFSWV9ESVJ9L2xpYgogIENPTU1BTkQgJHtDTUFLRV9DT01NQU5EfSAtRSBjb3B5ICR7QVJDSF9ESVJ9L2xpYmZvby5zbyAke0NNQUtFX0JJTkFSWV9ESVJ9L2xpYi8pCmBgYAoKQnVpbGQgdGhlbSBmb3IgYm90aCBhcmNoZXMgKGB4ODZfNjRgLCBgYWFyY2g2NGApIG9uIFVidW50dSAyNC4wNCBzbyB0aGV5IG1hdGNoIHRoZSByb2JvdC4KU3RhdGljIGxpbmtpbmcgd29ya3MgdG9vIGFuZCBuZWVkcyBubyBidW5kbGluZy4gRm9yIGFuIHJjbGNwcCBub2RlLCBgaW5zdGFsbChGSUxFUyAuLi4gREVTVElOQVRJT04gbGliKWAKaW5zdGVhZCDigJQgdGhlIG5vZGUgZmluZHMgYGluc3RhbGwtPGFyY2g+Lzxwa2c+L2xpYi9gIHRoZSBzYW1lIHdheS4KLS0tCgojIyBTd2l0Y2hpbmcgYmFja2VuZCB0eXBlCgpgYGBiYXNoCm11c2NhdC1wayB0eXBlIGNoYW5nZSAgICAgICAgICAgICAgICAgIyBpbnRlcmFjdGl2ZQptdXNjYXQtcGsgdHlwZSBjaGFuZ2UgLS10byBjcHAgICAgICAgICMg4oaSIEMrKwptdXNjYXQtcGsgdHlwZSBjaGFuZ2UgLS10byByb3MyICAgICAgICMg4oaSIFJPUzIgKHJjbHB5IC8gUHl0aG9uKQptdXNjYXQtcGsgdHlwZSBjaGFuZ2UgLS10byByb3MyLWNwcCAgICMg4oaSIFJPUzIgKHJjbGNwcCAvIEMrKykKbXVzY2F0LXBrIHR5cGUgY2hhbmdlIC0tdG8gcHl0aG9uICAgICAjIOKGkiBQeXRob24KYGBgCgo+IEV4aXN0aW5nIGJhY2tlbmQgZGlycyAoYHJvczJfd3MvYCwgYGNwcC9gKSBhcmUgbm90IGRlbGV0ZWQgd2hlbiBzd2l0Y2hpbmcgYXdheS4gUmVtb3ZlIHRoZW0gbWFudWFsbHkgaWYgbm8gbG9uZ2VyIG5lZWRlZC4KCj4gU3dpdGNoaW5nIGJldHdlZW4gYSBQeXRob24gYW5kIGEgQysrIGJhY2tlbmQgYXNrcyB3aGV0aGVyIHRvIHJlcGxhY2UgdGhpcyBSRUFETUUgd2l0aCB0aGUgbWF0Y2hpbmcgb25lICh0aGUgb2xkIGZpbGUgaXMga2VwdCBhcyBgUkVBRE1FLm1kLmJha2ApLiBBZGQgYC0tcmVhZG1lYCB0byBhbnN3ZXIgeWVzIHdpdGhvdXQgdGhlIHByb21wdC4KCi0tLQoKIyMgQUkgY29kaW5nIGFzc2lzdGFudHMgKE1DUCkKCklmIHlvdSBidWlsZCB5b3VyIHBsdWdpbiB3aXRoIGFuIEFJIGFzc2lzdGFudCAoQ2xhdWRlIENvZGUsIENvZGV4LCDigKYpLCBnaXZlIGl0Cmdyb3VuZGVkIGtub3dsZWRnZSBvZiB0aGUgTXVzY2F0IFVJIGNvbXBvbmVudHMsIGRlc2lnbiB0b2tlbnMsIGFuZCBTREsgaW5zdGVhZCBvZgpsZXR0aW5nIGl0IGd1ZXNzLiBgbXVzY2F0LXBrIG1jcGAgaXMgYW4gTUNQIHNlcnZlciBleHBvc2luZzoKCi0gYGxpc3RfY29tcG9uZW50c2AgLyBgZ2V0X2NvbXBvbmVudF9wcm9wc2AgLyBgZ2V0X2NvbXBvbmVudF9leGFtcGxlYCDigJQgZXZlcnkKICBgQHJhaW5ib3ctcm9ib3RpY3MvcGx1Z2luLXVpL3JlYWN0YCBjb21wb25lbnQgd2l0aCBpdHMgcmVhbCBwcm9wcyBhbmQgYSB3b3JraW5nCiAgU3Rvcnlib29rIGV4YW1wbGUuCi0gYGxpc3RfZGVzaWduX3Rva2Vuc2AgLyBgc2VhcmNoX2Rlc2lnbl90b2tlbnNgIOKAlCB0aGUgVGFpbHdpbmQgY2xhc3NlcyB0byB1c2UKICAoYGJnLWJnLSpgLCBgdGV4dC1mZy0qYCwgYHR5cG8tKmAsIOKApikgc28geW91ciBVSSBtYXRjaGVzIHRoZSBob3N0IHRoZW1lLgotIGBzZWFyY2hfcmJfc2RrYCDigJQgaG93IHRvIHVzZSBgdXNlUmIoKWAsIGByYi4qYCwgYHVzZVJiRm9ybURhdGFgL2B1c2VSYlNhdmVgLCBhbmQKICB0aGUgYmFja2VuZCBydW50aW1lcy4KLSBgbGlzdF9yYl9zZGtgIC8gYGdldF9yYl9zZGtfYXBpYCDigJQgdGhlIGluc3RhbGxlZCBgcmFpbmJvdy1yYi1zZGtgIChQeXRob24KICBiYWNrZW5kKSBjbGFzc2VzIGFuZCBzaWduYXR1cmVzOyB3aXRoIGBsYW5nOiAiY3BwImAsIHRoZSBDKysgU0RLIGhlYWRlcnMKICAoYHJhaW5ib3ctcmItc2RrLWRldmAsIHJlYWQgb3V0IG9mIHRoZSBgbXVzY2F0LXBrYCBjcHAgZGV2IGltYWdlIOKAlCBidWlsZCBpdAogIG9uY2Ugd2l0aCBgbXVzY2F0LXBrIGRldjpiYWNrYCkuCi0gYGNoZWNrX3Byb2plY3RgIOKAlCB3aGF0IHRoaXMgcHJvamVjdCBtdXN0IGNoYW5nZSBmb3IgdGhlIHBsdWdpbi11aSBpdCBoYXMKICBpbnN0YWxsZWQgKG9sZCBBUElzIHN1Y2ggYXMgYGNvbm5lY3QoQXBwKWAgb3IgYFNsaWRlcmAsIGEgYHZpdGUuY29uZmlnYCB3aXRob3V0CiAgdGhlIGBtdXNjYXQoKWAgcHJlc2V0LCBgdHNjYCBlcnJvcnMpLCB0aGUgc2FtZSBsaXN0IGBtdXNjYXQtcGsgdXBkYXRlYCBwcmludHMuCiAgQXNrIHRoZSBhc3Npc3RhbnQgdG8gZml4IHRoZSBwcm9qZWN0IGFmdGVyIGFuIHVwZGF0ZTsgaXQgcmUtY2hlY2tzIHVudGlsIGNsZWFuLgoKKipCcm93c2UgdGhlIGNvbXBvbmVudHMgbGl2ZSoqIHdpdGggYG11c2NhdC1wayBzdG9yeWJvb2tgLgoKYG11c2NhdC1wayBuZXdgIGFsc28gd3JpdGVzIGBBR0VOVFMubWRgIChyZWFkIGJ5IENvZGV4LCBDdXJzb3IsIEdlbWluaSBDTEksIENvcGlsb3QpCmFuZCBhIGBDTEFVREUubWRgIHRoYXQgaW1wb3J0cyBpdDogdGhlIFVJIHJ1bGVzIChwbHVnaW4tdWkgY29tcG9uZW50cyBpbnN0ZWFkIG9mCm5hdGl2ZSBgPHNlbGVjdD5gL2A8aW5wdXQ+YC9gPGJ1dHRvbj5gLCBkZXNpZ24gdG9rZW5zIGZvciBjb2xvcnMpIGZvciBhc3Npc3RhbnRzIHRoYXQKZG8gbm90IGNhbGwgdGhlIE1DUCB0b29scyBvbiB0aGVpciBvd24uIEFkZCB5b3VyIG93biBwcm9qZWN0IG5vdGVzIHRoZXJlLgoKIyMjIFJlZ2lzdGVyIHRoZSBzZXJ2ZXIKCioqQ2xhdWRlIENvZGUqKiDigJQgYSBgLm1jcC5qc29uYCBpcyBhbHJlYWR5IHNjYWZmb2xkZWQgYXQgeW91ciBwbHVnaW4gcm9vdCwgc28KaXQgd29ya3Mgb3V0IG9mIHRoZSBib3g6CgpgYGBqc29uCnsKICAibWNwU2VydmVycyI6IHsKICAgICJtdXNjYXQiOiB7CiAgICAgICJjb21tYW5kIjogIm11c2NhdC1wayIsCiAgICAgICJhcmdzIjogWyJtY3AiXQogICAgfQogIH0KfQpgYGAKCioqQ29kZXgqKiDigJQgcmVnaXN0ZXIgb25jZSB3aXRoOgoKYGBgYmFzaAptdXNjYXQtcGsgbWNwIC0taW5zdGFsbCBjb2RleApgYGAKClRoaXMgYXBwZW5kcyB0aGUgc2VydmVyIHRvIGB+Ly5jb2RleC9jb25maWcudG9tbGAgKGlkZW1wb3RlbnQg4oCUIHNhZmUgdG8gcnVuCmFnYWluKS4gRXF1aXZhbGVudCBtYW51YWwgY29uZmlnOgoKYGBgdG9tbApbbWNwX3NlcnZlcnMubXVzY2F0XQpjb21tYW5kID0gIm11c2NhdC1wayIKYXJncyA9IFsibWNwIl0KYGBgCgpBbnkgb3RoZXIgTUNQIGNsaWVudCB3b3JrcyB0b28g4oCUIGl0J3MgYSBzdGFuZGFyZCBzdGRpbyBNQ1Agc2VydmVyIHN0YXJ0ZWQgd2l0aApgbXVzY2F0LXBrIG1jcGAuIElmIGBtdXNjYXQtcGtgIGlzbid0IG9uIHRoZSBjbGllbnQncyBQQVRILCB1c2UgaXRzIGFic29sdXRlIHBhdGgKKGB3aGljaCBtdXNjYXQtcGtgKSBhcyBgY29tbWFuZGAuCgotLS0KCiMjIFNoaXBwaW5nCgpgYGBiYXNoCm11c2NhdC1wayBidWlsZCAgICAgICAgICAgICMgYnVpbGQgKyBaSVAKbXVzY2F0LXBrIGJ1aWxkIC0tbm8temlwICAgIyBidWlsZCBvbmx5LCBubyBaSVAKYGBgCgo+IEJ1aWxkaW5nIHRoZSBvdGhlciBhcmNoIChlLmcuIGFybTY0IG9uIGFuIGFtZDY0IFBDKSBydW5zIGluIGFuIGVtdWxhdGVkIGNvbnRhaW5lciBmb3IKPiBDKysgYmFja2VuZHMuIERvY2tlciBEZXNrdG9wIGhhcyBpdCBidWlsdCBpbjsgb24gTGludXggZW5hYmxlIGl0IG9uY2Ugd2l0aAo+IGBkb2NrZXIgcnVuIC0tcHJpdmlsZWdlZCAtLXJtIHRvbmlzdGlpZ2kvYmluZm10IC0taW5zdGFsbCBhbGxgLCBvciBwYXNzIGAtLWFyY2hgIGZvciBvbmUgYXJjaC4KCi0gQnVpbGRzIGB1aS9jb250ZW50LnRzeGAg4oaSIGBkaXN0L2NvbnRlbnQuanNgIChtaW5pZmllZCkKLSBDb21waWxlcyBgY3BwL2AgKFJlbGVhc2UpIGluIHRoZSBVYnVudHUgMjQuMDQgY29udGFpbmVyIHBlciBhcmNoIOKGkiBgZGlzdC88YXJjaD4vPGVudHJ5PmAgKyBgZGlzdC88YXJjaD4vbGliL2xpYnJiX3Nkay5zby4qYAotIFJPUzIgKHJjbGNwcCk6IHJ1bnMgYGNvbGNvbiBidWlsZGAgcGVyIGFyY2gg4oaSIGBkaXN0L3JvczJfd3MvaW5zdGFsbC08YXJjaD4vYAotIENvcGllcyBgYXNzZXRzL2AsIGBtYW5pZmVzdC5qc29uYCwgYW5kIGBSRUFETUUqLm1kYCBpbnRvIGBkaXN0L2AKLSBPdXRwdXQ6IGBfX1BMVUdJTl9ESVJfXy17dmVyc2lvbn0uemlwYAoKWklQIGxheW91dDoKCmBgYApfX1BMVUdJTl9ESVJfXy0xLjAuMC56aXAK4pSc4pSAIGRpc3QvCuKUgiAgIOKUnOKUgCBjb250ZW50LmpzICAgICAgICAjIGJ1aWx0IFVJCuKUgiAgIOKUnOKUgCBtYW5pZmVzdC5qc29uCuKUgiAgIOKUnOKUgCBhc3NldHMvCuKUgiAgIOKUnOKUgCBSRUFETUUubWQK4pSCICAg4pSc4pSAIFJFQURNRS5rby5tZCAgICAgICMgaWYgcHJlc2VudArilIIgICDilJzilIAgYW1kNjQvICAgICAgICAgICAgIyBjcHA6IDxlbnRyeT4gKyBsaWIvbGlicmJfc2RrLnNvLioK4pSCICAg4pSc4pSAIGFybTY0LwrilIIgICDilJTilIAgcm9zMl93cy8gICAgICAgICAgIyByY2xjcHA6IGluc3RhbGwtYW1kNjQvLCBpbnN0YWxsLWFybTY0LwpgYGAKCi0tLQoKIyMgQWxsIGNvbW1hbmRzCgpgYGBiYXNoCm11c2NhdC1wayBkZXYgICAgICAgICMgVUkgKyBiYWNrZW5kCm11c2NhdC1wayBkZXY6dWkgICAgICMgVUkgcHJldmlldyBvbmx5IChwcmV2aWV3LWhvc3QpCm11c2NhdC1wayBkZXY6YmFjayAgICMgYmFja2VuZCBvbmx5IChDKysgcmVidWlsZCArIHJlc3RhcnQgaW4gRG9ja2VyKQptdXNjYXQtcGsgYnVpbGQgICAgICAjIGJ1aWxkIOKGkiBkaXN0LyArIGRpc3RyaWJ1dGFibGUgWklQICgtLW5vLXppcCB0byBza2lwKQptdXNjYXQtcGsgc3Rvcnlib29rICAjIGJyb3dzZSB0aGUgcmItY29tcG9uZW50cyBVSSBsaWJyYXJ5IGluIGEgYnJvd3NlcgptdXNjYXQtcGsgbWNwICAgICAgICAjIE1DUCBzZXJ2ZXIgZm9yIEFJIGFzc2lzdGFudHMgKGNvbXBvbmVudHMvdG9rZW5zL1NESyBkb2NzKQpgYGAKCmBgYGJhc2gKbXVzY2F0LXBrIHR5cGUgY2hhbmdlICAgICMgc3dpdGNoIGJhY2tlbmQgdHlwZQptdXNjYXQtcGsgdXBkYXRlICAgICAgICAgIyB1cGRhdGUgbXVzY2F0LXBsdWdpbi1raXQgaXRzZWxmCm11c2NhdC1wayB1bmluc3RhbGwgICAgICAjIHJlbW92ZSBtdXNjYXQtcGsgaXRzZWxmCmBgYAo=","ros2/ros2_ws/src/__PLUGIN_SLUG__/__PLUGIN_SLUG__/__init__.py":"","ros2/ros2_ws/src/__PLUGIN_SLUG__/__PLUGIN_SLUG__/node.py":"aW1wb3J0IHJjbHB5CmZyb20gcmNscHkubm9kZSBpbXBvcnQgTm9kZQpmcm9tIHJhaW5ib3cucmJfc2RrIGltcG9ydCBSQk1hbmlwdWxhdGVTREssIFJCUGx1Z2luQ2FsbCAgIyBQeVBJOiByYWluYm93LXJiLXNkawoKCnNkayA9IFJCTWFuaXB1bGF0ZVNESygpCnBsdWdpbiA9IFJCUGx1Z2luQ2FsbCgpCgoKIyBFeHRlcm5hbCBlbmRwb2ludCAoUkVTVCAvIFNvY2tldC5JTyAvIFRDUCAvIE1RVFQgLyBXZWJSVEMpLCBlLmcuCiMgICBjdXJsIC1YIFBPU1QgaHR0cDovLzxyb2JvdD4vY29tbW9uL3BsdWdpbi88cGx1Z2luX2lkPi9oZWxsbyAtZCAneyJuYW1lIjogImtpbSJ9JwpAcGx1Z2luLnJvdXRlci5vbigiL2hlbGxvIikKZGVmIGhlbGxvKHBheWxvYWQ9Tm9uZSwgbWV0YT1Ob25lKToKICAgIG5hbWUgPSAocGF5bG9hZCBvciB7fSkuZ2V0KCJuYW1lIiwgInRoZXJlIikKICAgIHJldHVybiB7Im1zZyI6IGYiaGkge25hbWV9IiwgInZpYSI6IChtZXRhIG9yIHt9KS5nZXQoInRyYW5zcG9ydCIpfQoKCmNsYXNzIF9fUExVR0lOX0NMQVNTX19Ob2RlKE5vZGUpOgogICAgZGVmIF9faW5pdF9fKHNlbGYpOgogICAgICAgIHN1cGVyKCkuX19pbml0X18oIl9fUExVR0lOX1NMVUdfX19ub2RlIikKICAgICAgICAjIEFsc28gY29ubmVjdHMgdGhlIHBsdWdpbiB0byBNdXNjYXQg4oCUIHJvdXRlciBoYW5kbGVycyByZWdpc3RlciBvbiB0aGUgZmlyc3QgY2FsbC4KICAgICAgICBwbHVnaW4ucHVibGlzaCgic3RhdGUiLCB7InJlYWR5IjogVHJ1ZSwgInBsdWdpbiI6ICJfX1BMVUdJTl9OQU1FX18ifSkgICMgLT4gVUkgcmIuc3ViKCJzdGF0ZSIpCiAgICAgICAgc2VsZi5nZXRfbG9nZ2VyKCkuaW5mbygiX19QTFVHSU5fTkFNRV9fIG5vZGUgc3RhcnRlZCIpCiAgICAgICAgIyBzZGsgaXMgYXZhaWxhYmxlIGhlcmUg4oCUIHVzZSBpdCBhbG9uZ3NpZGUgUk9TMiB0b3BpY3MgYXMgbmVlZGVkCgoKZGVmIG1haW4oYXJncz1Ob25lKToKICAgIHJjbHB5LmluaXQoYXJncz1hcmdzKQogICAgbm9kZSA9IF9fUExVR0lOX0NMQVNTX19Ob2RlKCkKICAgIHJjbHB5LnNwaW4obm9kZSkKICAgIG5vZGUuZGVzdHJveV9ub2RlKCkKICAgIHJjbHB5LnNodXRkb3duKCkKCgppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOgogICAgbWFpbigpCg==","ros2/ros2_ws/src/__PLUGIN_SLUG__/package.xml":"PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxwYWNrYWdlIGZvcm1hdD0iMyI+CiAgPG5hbWU+X19QTFVHSU5fU0xVR19fPC9uYW1lPgogIDx2ZXJzaW9uPjAuMC4xPC92ZXJzaW9uPgogIDxkZXNjcmlwdGlvbj5fX1BMVUdJTl9OQU1FX18gUk9TMiBub2RlPC9kZXNjcmlwdGlvbj4KICA8bWFpbnRhaW5lciBlbWFpbD0idG9kb0BleGFtcGxlLmNvbSI+bWFpbnRhaW5lcjwvbWFpbnRhaW5lcj4KICA8bGljZW5zZT5Qcm9wcmlldGFyeTwvbGljZW5zZT4KICA8ZGVwZW5kPnJjbHB5PC9kZXBlbmQ+CiAgPGV4cG9ydD48YnVpbGRfdHlwZT5hbWVudF9weXRob248L2J1aWxkX3R5cGU+PC9leHBvcnQ+CjwvcGFja2FnZT4K","ros2/ros2_ws/src/__PLUGIN_SLUG__/resource/__PLUGIN_SLUG__":"","ros2/ros2_ws/src/__PLUGIN_SLUG__/setup.py":"ZnJvbSBzZXR1cHRvb2xzIGltcG9ydCBzZXR1cAoKcGFja2FnZV9uYW1lID0gIl9fUExVR0lOX1NMVUdfXyIKCnNldHVwKAogICAgbmFtZT1wYWNrYWdlX25hbWUsCiAgICB2ZXJzaW9uPSIwLjAuMSIsCiAgICBwYWNrYWdlcz1bcGFja2FnZV9uYW1lXSwKICAgIGRhdGFfZmlsZXM9WwogICAgICAgICgic2hhcmUvYW1lbnRfaW5kZXgvcmVzb3VyY2VfaW5kZXgvcGFja2FnZXMiLCBbInJlc291cmNlLyIgKyBwYWNrYWdlX25hbWVdKSwKICAgICAgICAoInNoYXJlLyIgKyBwYWNrYWdlX25hbWUsIFsicGFja2FnZS54bWwiXSksCiAgICBdLAogICAgaW5zdGFsbF9yZXF1aXJlcz1bInNldHVwdG9vbHMiXSwKICAgIHppcF9zYWZlPVRydWUsCiAgICBlbnRyeV9wb2ludHM9ewogICAgICAgICJjb25zb2xlX3NjcmlwdHMiOiBbIl9fUExVR0lOX1NMVUdfX19ub2RlID0gX19QTFVHSU5fU0xVR19fLm5vZGU6bWFpbiJdLAogICAgfSwKKQo=","ros2-cpp/ros2_ws/src/__PLUGIN_SLUG__/CMakeLists.txt":"Y21ha2VfbWluaW11bV9yZXF1aXJlZChWRVJTSU9OIDMuMTYpCnByb2plY3QoX19QTFVHSU5fU0xVR19fKQoKaWYoTk9UIENNQUtFX0NYWF9TVEFOREFSRCkKICBzZXQoQ01BS0VfQ1hYX1NUQU5EQVJEIDE3KQplbmRpZigpCgpmaW5kX3BhY2thZ2UoYW1lbnRfY21ha2UgUkVRVUlSRUQpCmZpbmRfcGFja2FnZShyY2xjcHAgUkVRVUlSRUQpCiMgUmFpbmJvdyBSb2JvdGljcyBDKysgU0RLIChhcHQ6IHJhaW5ib3ctcmItc2RrLWRldiwgcHJlLWluc3RhbGxlZCBpbiB0aGUgZGV2CiMgY29udGFpbmVyKS4gVGhlIHZlcnNpb24gaGVyZSBpcyB0aGUgb25lIHRoZSBkZXYgY29udGFpbmVyIGluc3RhbGxzOyBjaGFuZ2UgaXQKIyB3aXRoIGBtdXNjYXQtcGsgc2RrIHVwZGF0ZSA8dmVyc2lvbj5gLgpmaW5kX3BhY2thZ2UocmJfc2RrIDAuMTAuMiBFWEFDVCBSRVFVSVJFRCkKCmFkZF9leGVjdXRhYmxlKF9fUExVR0lOX1NMVUdfX19ub2RlIHNyYy9ub2RlLmNwcCkKYW1lbnRfdGFyZ2V0X2RlcGVuZGVuY2llcyhfX1BMVUdJTl9TTFVHX19fbm9kZSByY2xjcHApCnRhcmdldF9saW5rX2xpYnJhcmllcyhfX1BMVUdJTl9TTFVHX19fbm9kZSByYl9zZGs6OnJiX3NkaykKCmluc3RhbGwoVEFSR0VUUyBfX1BMVUdJTl9TTFVHX19fbm9kZQogIERFU1RJTkFUSU9OIGxpYi8ke1BST0pFQ1RfTkFNRX0pCgphbWVudF9wYWNrYWdlKCkK","ros2-cpp/ros2_ws/src/__PLUGIN_SLUG__/package.xml":"PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxwYWNrYWdlIGZvcm1hdD0iMyI+CiAgPG5hbWU+X19QTFVHSU5fU0xVR19fPC9uYW1lPgogIDx2ZXJzaW9uPjAuMC4xPC92ZXJzaW9uPgogIDxkZXNjcmlwdGlvbj5fX1BMVUdJTl9OQU1FX18gUk9TMiBub2RlIChyY2xjcHApPC9kZXNjcmlwdGlvbj4KICA8bWFpbnRhaW5lciBlbWFpbD0idG9kb0BleGFtcGxlLmNvbSI+bWFpbnRhaW5lcjwvbWFpbnRhaW5lcj4KICA8bGljZW5zZT5Qcm9wcmlldGFyeTwvbGljZW5zZT4KICA8YnVpbGR0b29sX2RlcGVuZD5hbWVudF9jbWFrZTwvYnVpbGR0b29sX2RlcGVuZD4KICA8ZGVwZW5kPnJjbGNwcDwvZGVwZW5kPgogIDxleHBvcnQ+PGJ1aWxkX3R5cGU+YW1lbnRfY21ha2U8L2J1aWxkX3R5cGU+PC9leHBvcnQ+CjwvcGFja2FnZT4K","ros2-cpp/ros2_ws/src/__PLUGIN_SLUG__/src/node.cpp":"Ly8gX19QTFVHSU5fTkFNRV9fIOKAlCBST1MyIG5vZGUgKHJjbGNwcCkuCi8vCi8vIFJlbGF0aXZlIHRvcGljIG5hbWVzIGxhbmQgdW5kZXIgdGhlIHBsdWdpbidzIFJPUyBuYW1lc3BhY2UgKHBsdWdpbiBpZCB3aXRoCi8vICIuIiDihpIgIi8iLCAiLSIg4oaSICJfIik7IHVzZSBhbiBhYnNvbHV0ZSBuYW1lICgiL2NtZF92ZWwiKSBmb3Igc2hhcmVkIHRvcGljcy4KLy8gVUkgbWVzc2FnaW5nIC8gZXh0ZXJuYWwgZW5kcG9pbnRzOiByYl9wbHVnaW46OlJCUGx1Z2luQ2FsbCAocGx1Z2luL3JiX3BsdWdpbi5ocHApLgojaW5jbHVkZSAicmNsY3BwL3JjbGNwcC5ocHAiCi8vIFJhaW5ib3cgUm9ib3RpY3MgQysrIFNESyAobGlua2VkIGFzIHJiX3Nkazo6cmJfc2RrKTogUkJNYW5pcHVsYXRlU0RLIGV0Yy4KI2luY2x1ZGUgPHJhaW5ib3cvcmJfc2RrL21hbmlwdWxhdGUvcmJfbWFuaXB1bGF0ZV9zZGsuaHBwPgojaW5jbHVkZSA8cmFpbmJvdy9yYl9zZGsvcGx1Z2luL3JiX3BsdWdpbi5ocHA+CgojaW5jbHVkZSA8bmxvaG1hbm4vanNvbi5ocHA+Cgp1c2luZyBubG9obWFubjo6anNvbjsKdXNpbmcgcmJfcGx1Z2luOjpSQlBsdWdpbkNhbGw7CgpjbGFzcyBfX1BMVUdJTl9DTEFTU19fTm9kZSA6IHB1YmxpYyByY2xjcHA6Ok5vZGUgewpwdWJsaWM6CiAgX19QTFVHSU5fQ0xBU1NfX05vZGUoKSA6IE5vZGUoIl9fUExVR0lOX1NMVUdfX19ub2RlIikgewogICAgUkNMQ1BQX0lORk8odGhpcy0+Z2V0X2xvZ2dlcigpLCAiX19QTFVHSU5fTkFNRV9fIG5vZGUgc3RhcnRlZCIpOwogICAgLy8gY3JlYXRlIHB1Ymxpc2hlcnMgLyBzdWJzY3JpYmVycyAvIHNlcnZpY2VzIGhlcmUKICB9Cn07CgppbnQgbWFpbihpbnQgYXJnYywgY2hhcioqIGFyZ3YpIHsKICByY2xjcHA6OmluaXQoYXJnYywgYXJndik7CgogIC8vIHBsdWdpbiBpZCBjb21lcyBmcm9tIFJCX1BMVUdJTl9JRC4KICBhdXRvIHBsdWdpbiA9IFJCUGx1Z2luQ2FsbDo6Z2V0X2luc3RhbmNlKFJCUGx1Z2luQ2FsbDo6cmVzb2x2ZV9wbHVnaW5faWQoc3RkOjpudWxsb3B0KSk7CiAgLy8gRXh0ZXJuYWwgZW5kcG9pbnQgKFJFU1QgLyBTb2NrZXQuSU8gLyBUQ1AgLyBNUVRUIC8gV2ViUlRDKSwgZS5nLgogIC8vICAgY3VybCAtWCBQT1NUIGh0dHA6Ly88cm9ib3Q+L2NvbW1vbi9wbHVnaW4vPHBsdWdpbl9pZD4vaGVsbG8gLWQgJ3sibmFtZSI6ImtpbSJ9JwogIHBsdWdpbi0+cm91dGVyKCkub24oIi9oZWxsbyIsIFtdKGNvbnN0IGpzb24mIHBheWxvYWQsIGNvbnN0IGpzb24mIG1ldGEpIHsKICAgIGNvbnN0IHN0ZDo6c3RyaW5nIHdobyA9IHBheWxvYWQuaXNfb2JqZWN0KCkgPyBwYXlsb2FkLnZhbHVlKCJuYW1lIiwgc3RkOjpzdHJpbmcoInRoZXJlIikpIDogInRoZXJlIjsKICAgIHJldHVybiBqc29ue3sibXNnIiwgImhpICIgKyB3aG99LCB7InZpYSIsIG1ldGEudmFsdWUoInRyYW5zcG9ydCIsIHN0ZDo6c3RyaW5nKCkpfX07CiAgfSk7CiAgLy8gQWxzbyBjb25uZWN0cyB0aGUgcGx1Z2luIHRvIE11c2NhdCDigJQgcm91dGVyIGhhbmRsZXJzIHJlZ2lzdGVyIG9uIHRoZSBmaXJzdCBjYWxsLgogIHBsdWdpbi0+cHVibGlzaCgic3RhdGUiLCB7eyJyZWFkeSIsIHRydWV9LCB7InBsdWdpbiIsICJfX1BMVUdJTl9OQU1FX18ifX0pOyAgLy8gLT4gVUkgcmIuc3ViKCJzdGF0ZSIpCgogIHJjbGNwcDo6c3BpbihzdGQ6Om1ha2Vfc2hhcmVkPF9fUExVR0lOX0NMQVNTX19Ob2RlPigpKTsKICByY2xjcHA6OnNodXRkb3duKCk7CiAgcmV0dXJuIDA7Cn0K","docker/Dockerfile.cpp":"IyBEZXYvYnVpbGQgY29udGFpbmVyIGZvciB0aGUgcHVyZSBDKysgcGx1Z2luIGJhY2sgZW5kLgojIE1hdGNoZXMgdGhlIE11c2NhdCByb2JvdCBiYWNrZW5kIE9TIChVYnVudHUgMjQuMDQpIHNvIHRoZSBjb21waWxlZCBiaW5hcnkKIyBpcyBBQkktY29tcGF0aWJsZSB3aXRoIHRoZSByb2JvdC4gVXNlZCBieSBgbXVzY2F0LXBrIGRldjpiYWNrYCBhbmQgYGJ1aWxkYAojIOKAlCBOT1Qgc2hpcHBlZCBpbiB0aGUgcGx1Z2luIFpJUC4KRlJPTSB1YnVudHU6MjQuMDQKTEFCRUwgY29tLnJhaW5ib3ctcm9ib3RpY3MubXVzY2F0LXBrPSJ0cnVlIgoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSAtLW5vLWluc3RhbGwtcmVjb21tZW5kcyBcCiAgICAgIGJ1aWxkLWVzc2VudGlhbCBcCiAgICAgIGNtYWtlIFwKICAgICYmIHJtIC1yZiAvdmFyL2xpYi9hcHQvbGlzdHMvKgoKIyBSYWluYm93IFJvYm90aWNzIEMrKyBTREsgZm9yIGZpbmRfcGFja2FnZShyYl9zZGspLiBtdXNjYXQtcGsgcGFzc2VzIHRoZSB2ZXJzaW9uIHBpbm5lZCBpbiB0aGUKIyBwcm9qZWN0J3MgQ01ha2VMaXN0cy50eHQgKGZpbmRfcGFja2FnZShyYl9zZGsgPHZlcj4gRVhBQ1QpKTsgd2l0aG91dCBhIHBpbiAoUk9TIDIgcmNscHksIGBtdXNjYXQtcGsgbWNwYAojIG91dHNpZGUgYSBwcm9qZWN0KSB0aGUgbmV3ZXN0IFNESyBpcyBpbnN0YWxsZWQuIFJ1bnRpbWUgYW5kIC1kZXYgYXJlIGluc3RhbGxlZCB0b2dldGhlciBhdCBvbmUgdmVyc2lvbi4KQVJHIFJCX1NES19WRVJTSU9OPQpSVU4gYXB0LWdldCB1cGRhdGUgJiYgYXB0LWdldCBpbnN0YWxsIC15IC0tbm8taW5zdGFsbC1yZWNvbW1lbmRzIGNhLWNlcnRpZmljYXRlcyBjdXJsIFwKICAgICYmIGluc3RhbGwgLWQgL2V0Yy9hcHQva2V5cmluZ3MgXAogICAgJiYgY3VybCAtZnNTTCBodHRwczovL3JhaW5ib3dyb2JvdGljcy5naXRodWIuaW8vcmItc2RrL3JiLXNkay1hcHQtcmVwby5ncGcua2V5IC1vIC9ldGMvYXB0L2tleXJpbmdzL3JiLXNkay5hc2MgXAogICAgJiYgcHJpbnRmICdkZWIgW3NpZ25lZC1ieT0vZXRjL2FwdC9rZXlyaW5ncy9yYi1zZGsuYXNjXSBodHRwczovL3JhaW5ib3dyb2JvdGljcy5naXRodWIuaW8vcmItc2RrICVzIG1haW5cbicgc3RhYmxlIGRldiA+IC9ldGMvYXB0L3NvdXJjZXMubGlzdC5kL3JiLXNkay5saXN0IFwKICAgICYmIGFwdC1nZXQgdXBkYXRlIFwKICAgICYmIGFwdC1nZXQgaW5zdGFsbCAteSAtLW5vLWluc3RhbGwtcmVjb21tZW5kcyAicmFpbmJvdy1yYi1zZGske1JCX1NES19WRVJTSU9OOis9JFJCX1NES19WRVJTSU9OfSIgInJhaW5ib3ctcmItc2RrLWRldiR7UkJfU0RLX1ZFUlNJT046Kz0kUkJfU0RLX1ZFUlNJT059IiBcCiAgICAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCgpXT1JLRElSIC9wbHVnaW4KCkNNRCBbImJhc2giXQo=","docker/Dockerfile.dev":"IyBEZXYtb25seSBjb250YWluZXIgZm9yIHRoZSBST1MyIHBsdWdpbiBiYWNrIGVuZC4KIyBNYXRjaGVzIHRoZSBNdXNjYXQgcm9ib3QgYmFja2VuZDogUk9TMiBKYXp6eSArIFB5dGhvbiAzLjEyIChVYnVudHUgMjQuMDQpLgojIFVzZWQgYnkgYG11c2NhdC1wayBkZXY6YmFja2Ag4oCUIE5PVCBzaGlwcGVkIGluIHRoZSBwbHVnaW4gWklQLgpGUk9NIHJvczpqYXp6eS1yb3MtYmFzZQpMQUJFTCBjb20ucmFpbmJvdy1yb2JvdGljcy5tdXNjYXQtcGs9InRydWUiCgpSVU4gYXB0LWdldCB1cGRhdGUgJiYgYXB0LWdldCBpbnN0YWxsIC15IC0tbm8taW5zdGFsbC1yZWNvbW1lbmRzIFwKICAgICAgcHl0aG9uMy1waXAgXAogICAgICBweXRob24zLWNvbGNvbi1jb21tb24tZXh0ZW5zaW9ucyBcCiAgICAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCiMgUmFpbmJvdyBSb2JvdGljcyBDKysgU0RLIGZvciBmaW5kX3BhY2thZ2UocmJfc2RrKS4gbXVzY2F0LXBrIHBhc3NlcyB0aGUgdmVyc2lvbiBwaW5uZWQgaW4gdGhlCiMgcHJvamVjdCdzIENNYWtlTGlzdHMudHh0IChmaW5kX3BhY2thZ2UocmJfc2RrIDx2ZXI+IEVYQUNUKSk7IHdpdGhvdXQgYSBwaW4gKFJPUyAyIHJjbHB5LCBgbXVzY2F0LXBrIG1jcGAKIyBvdXRzaWRlIGEgcHJvamVjdCkgdGhlIG5ld2VzdCBTREsgaXMgaW5zdGFsbGVkLiBSdW50aW1lIGFuZCAtZGV2IGFyZSBpbnN0YWxsZWQgdG9nZXRoZXIgYXQgb25lIHZlcnNpb24uCkFSRyBSQl9TREtfVkVSU0lPTj0KUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSAtLW5vLWluc3RhbGwtcmVjb21tZW5kcyBjYS1jZXJ0aWZpY2F0ZXMgY3VybCBcCiAgICAmJiBpbnN0YWxsIC1kIC9ldGMvYXB0L2tleXJpbmdzIFwKICAgICYmIGN1cmwgLWZzU0wgaHR0cHM6Ly9yYWluYm93cm9ib3RpY3MuZ2l0aHViLmlvL3JiLXNkay9yYi1zZGstYXB0LXJlcG8uZ3BnLmtleSAtbyAvZXRjL2FwdC9rZXlyaW5ncy9yYi1zZGsuYXNjIFwKICAgICYmIHByaW50ZiAnZGViIFtzaWduZWQtYnk9L2V0Yy9hcHQva2V5cmluZ3MvcmItc2RrLmFzY10gaHR0cHM6Ly9yYWluYm93cm9ib3RpY3MuZ2l0aHViLmlvL3JiLXNkayAlcyBtYWluXG4nIHN0YWJsZSBkZXYgPiAvZXRjL2FwdC9zb3VyY2VzLmxpc3QuZC9yYi1zZGsubGlzdCBcCiAgICAmJiBhcHQtZ2V0IHVwZGF0ZSBcCiAgICAmJiBhcHQtZ2V0IGluc3RhbGwgLXkgLS1uby1pbnN0YWxsLXJlY29tbWVuZHMgInJhaW5ib3ctcmItc2RrJHtSQl9TREtfVkVSU0lPTjorPSRSQl9TREtfVkVSU0lPTn0iICJyYWluYm93LXJiLXNkay1kZXYke1JCX1NES19WRVJTSU9OOis9JFJCX1NES19WRVJTSU9OfSIgXAogICAgJiYgcm0gLXJmIC92YXIvbGliL2FwdC9saXN0cy8qCgoKIyBgZG9ja2VyIGV4ZWNgIHNraXBzIC9yb3NfZW50cnlwb2ludC5zaCDigJQgc291cmNlIFJPUyBmb3IgdGhlIGxvZ2luIHNoZWxscyBkZXY6YmFjayBydW5zLgpSVU4gZWNobyAiLiAvb3B0L3Jvcy8ke1JPU19ESVNUUk99L3NldHVwLnNoIiA+IC9ldGMvcHJvZmlsZS5kL3Jvcy5zaAoKV09SS0RJUiAvcGx1Z2luCgpDTUQgWyJiYXNoIl0K","docker/Dockerfile.python":"IyBEZXYvYnVpbGQgY29udGFpbmVyIGZvciB0aGUgUHl0aG9uIHBsdWdpbiBiYWNrIGVuZC4KIyBNYXRjaGVzIHRoZSBNdXNjYXQgcm9ib3QgYmFja2VuZDogVWJ1bnR1IDI0LjA0ICsgUHl0aG9uIDMuMTIuCiMgVXNlZCBieSBgbXVzY2F0LXBrIGRldjpiYWNrYCAoaG90LXJlbG9hZCkgYW5kIGBtdXNjYXQtcGsgYnVpbGRgIChsb2NrICsgd2hlZWwgdmVuZG9yKS4KIyBOT1Qgc2hpcHBlZCBpbiB0aGUgcGx1Z2luIFpJUCDigJQgdGhlIHJvYm90IGluc3RhbGxzIGRlcHMgZnJvbSBkaXN0L3doZWVscy8gb2ZmbGluZS4KRlJPTSB1YnVudHU6MjQuMDQKTEFCRUwgY29tLnJhaW5ib3ctcm9ib3RpY3MubXVzY2F0LXBrPSJ0cnVlIgoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSAtLW5vLWluc3RhbGwtcmVjb21tZW5kcyBcCiAgICAgIHB5dGhvbjMgXAogICAgICBweXRob24zLXBpcCBcCiAgICAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyogXAogICAgJiYgcGlwMyBpbnN0YWxsIHV2PT0wLjguMTggLS1icmVhay1zeXN0ZW0tcGFja2FnZXMKCiMgVE9ETyhjcHAtc2RrKTogdGhlIFB5dGhvbiBTREsgaXMgYSBweWJpbmQgd3JhcHBlciBvdmVyIHRoZSBjcHAgU0RLLCBzbyB0aGUKIyBjcHAgU0RLIHNoYXJlZCBsaWIgbXVzdCBiZSBwcmVzZW50IGZvciB0aGUgcHl0aG9uIG1vZHVsZSB0byBsb2FkLiBJbnN0YWxsIHRoZQojIHJhaW5ib3cgY3BwIFNESyAoYXB0LCBwaW5uZWQgdG8gdGhlIHJvYm90J3MgdmVyc2lvbikgaGVyZSBvbmNlIGl0IGV4aXN0cy4KCgpXT1JLRElSIC9wbHVnaW4KCkNNRCBbImJhc2giXQo="};
|
package/cli/src/type.mjs
CHANGED
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
// muscat-pk type change — switch an existing plugin's backend type.
|
|
2
|
-
// python
|
|
3
|
-
// the
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
2
|
+
// python | cpp | ros2 (rclpy) | ros2-cpp (rclcpp).
|
|
3
|
+
// Adds the matching backend overlay; never deletes existing user code
|
|
4
|
+
// (e.g. ros2_ws/ or cpp/ are left in place when switching away).
|
|
5
|
+
import { copyFileSync, existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
6
|
+
import { tmpdir } from "node:os";
|
|
7
|
+
import { basename, join, resolve } from "node:path";
|
|
8
|
+
import { findPluginRoot, log, prompt, templatesDir } from "./util.mjs";
|
|
9
|
+
import {
|
|
10
|
+
TYPE_CHOICES,
|
|
11
|
+
applyTokens,
|
|
12
|
+
copyTemplate,
|
|
13
|
+
deriveNames,
|
|
14
|
+
overlayCpp,
|
|
15
|
+
overlayRos2,
|
|
16
|
+
prepareCppIde,
|
|
17
|
+
runtimeForChoice,
|
|
18
|
+
} from "./new.mjs";
|
|
9
19
|
|
|
10
|
-
const TYPES =
|
|
11
|
-
|
|
12
|
-
async function prompt(question, fallback) {
|
|
13
|
-
if (!process.stdin.isTTY) return fallback;
|
|
14
|
-
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
15
|
-
const answer = (await rl.question(question)).trim();
|
|
16
|
-
rl.close();
|
|
17
|
-
return answer || fallback;
|
|
18
|
-
}
|
|
20
|
+
const TYPES = Object.keys(TYPE_CHOICES);
|
|
19
21
|
|
|
20
22
|
function readManifest(root) {
|
|
21
23
|
const path = resolve(root, "manifest.json");
|
|
@@ -23,45 +25,77 @@ function readManifest(root) {
|
|
|
23
25
|
return { path, json: JSON.parse(readFileSync(path, "utf8")) };
|
|
24
26
|
}
|
|
25
27
|
|
|
28
|
+
// Derive the current `--type`-style key from a manifest runtime block.
|
|
29
|
+
function currentTypeKey(runtime) {
|
|
30
|
+
if (runtime?.type === "ros2") return runtime.rosClient === "rclcpp" ? "ros2-cpp" : "ros2";
|
|
31
|
+
return runtime?.type ?? "python";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const isCpp = (key) => key === "cpp" || key === "ros2-cpp";
|
|
35
|
+
|
|
36
|
+
async function offerReadme(root, toCpp, force, tokens) {
|
|
37
|
+
const lang = toCpp ? "C++" : "Python";
|
|
38
|
+
const answer = force ? "y" : await prompt(`Replace README.md with the ${lang} backend version? (current file kept as README.md.bak) [y/N]: `, "n");
|
|
39
|
+
if (!/^y/i.test(answer)) {
|
|
40
|
+
log.info(`README.md kept — to swap it later: muscat-pk type change --to <type> --readme`);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const tmp = mkdtempSync(join(tmpdir(), "muscat-pk-readme-"));
|
|
44
|
+
try {
|
|
45
|
+
await copyTemplate(resolve(templatesDir, toCpp ? "readme-cpp" : "common"), tmp);
|
|
46
|
+
applyTokens(tmp, tokens);
|
|
47
|
+
const readme = resolve(root, "README.md");
|
|
48
|
+
if (existsSync(readme)) copyFileSync(readme, resolve(root, "README.md.bak"));
|
|
49
|
+
copyFileSync(join(tmp, "README.md"), readme);
|
|
50
|
+
log.ok(`README.md → ${lang} version${existsSync(resolve(root, "README.md.bak")) ? " (previous file: README.md.bak)" : ""}`);
|
|
51
|
+
} finally {
|
|
52
|
+
rmSync(tmp, { recursive: true, force: true });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
26
56
|
export async function runType(args) {
|
|
27
|
-
// accept `type change`, `type`, `type --to ros2`
|
|
57
|
+
// accept `type change`, `type`, `type --to ros2-cpp`
|
|
28
58
|
const sub = args[0];
|
|
29
59
|
const toFlagIdx = args.indexOf("--to");
|
|
30
60
|
let to = toFlagIdx >= 0 ? args[toFlagIdx + 1] : undefined;
|
|
31
61
|
|
|
32
62
|
const root = findPluginRoot();
|
|
33
63
|
const { path, json } = readManifest(root);
|
|
34
|
-
const current = json.runtime
|
|
64
|
+
const current = currentTypeKey(json.runtime);
|
|
35
65
|
|
|
36
66
|
if (sub && sub !== "change") {
|
|
37
|
-
log.warn(`unknown subcommand '${sub}'. Usage: muscat-pk type change [--to python|ros2]`);
|
|
67
|
+
log.warn(`unknown subcommand '${sub}'. Usage: muscat-pk type change [--to python|cpp|ros2|ros2-cpp] [--readme]`);
|
|
38
68
|
}
|
|
39
69
|
|
|
40
70
|
if (!to) {
|
|
41
|
-
console.log(`\
|
|
42
|
-
console.log("
|
|
71
|
+
console.log(`\nCurrent type: ${current}`);
|
|
72
|
+
console.log("Select the new type:");
|
|
43
73
|
console.log(" 1) Python");
|
|
44
|
-
console.log(" 2)
|
|
45
|
-
|
|
46
|
-
|
|
74
|
+
console.log(" 2) C++");
|
|
75
|
+
console.log(" 3) ROS2 (rclpy / Python)");
|
|
76
|
+
console.log(" 4) ROS2 (rclcpp / C++)");
|
|
77
|
+
const choice = await prompt("\nChoice [1/2/3/4]: ", "");
|
|
78
|
+
to = { "1": "python", "2": "cpp", "3": "ros2", "4": "ros2-cpp" }[choice];
|
|
47
79
|
}
|
|
48
80
|
|
|
49
81
|
if (!TYPES.includes(to)) {
|
|
50
|
-
throw new Error(`invalid type. choose python
|
|
82
|
+
throw new Error(`invalid type. choose python | cpp | ros2 | ros2-cpp.`);
|
|
51
83
|
}
|
|
52
84
|
if (to === current) {
|
|
53
85
|
log.info(`already '${current}' — nothing to change.`);
|
|
54
86
|
return;
|
|
55
87
|
}
|
|
56
88
|
|
|
57
|
-
|
|
58
|
-
|
|
89
|
+
const runtimeChoice = TYPE_CHOICES[to];
|
|
90
|
+
const { dir, slug, pluginName, pluginClass, pluginId } = deriveNames(root);
|
|
91
|
+
|
|
92
|
+
if (runtimeChoice.type === "ros2") {
|
|
59
93
|
if (existsSync(resolve(root, "ros2_ws"))) {
|
|
60
94
|
log.warn("ros2_ws/ already exists — keeping it, only flipping manifest type.");
|
|
61
95
|
} else {
|
|
62
|
-
log.step(
|
|
63
|
-
overlayRos2(root, slug);
|
|
64
|
-
applyTokens(root, {
|
|
96
|
+
log.step(`adding ros2_ws/ overlay (${runtimeChoice.rosClient})`);
|
|
97
|
+
await overlayRos2(root, slug, runtimeChoice.rosClient);
|
|
98
|
+
applyTokens(resolve(root, "ros2_ws"), {
|
|
65
99
|
__PLUGIN_ID__: pluginId,
|
|
66
100
|
__PLUGIN_NAME__: pluginName,
|
|
67
101
|
__PLUGIN_SLUG__: slug,
|
|
@@ -69,14 +103,39 @@ export async function runType(args) {
|
|
|
69
103
|
__RUNTIME_TYPE__: "ros2",
|
|
70
104
|
});
|
|
71
105
|
}
|
|
106
|
+
} else if (runtimeChoice.type === "cpp") {
|
|
107
|
+
if (existsSync(resolve(root, "cpp"))) {
|
|
108
|
+
log.warn("cpp/ already exists — keeping it, only flipping manifest type.");
|
|
109
|
+
} else {
|
|
110
|
+
log.step("adding cpp/ overlay");
|
|
111
|
+
await overlayCpp(root);
|
|
112
|
+
applyTokens(resolve(root, "cpp"), {
|
|
113
|
+
__PLUGIN_ID__: pluginId,
|
|
114
|
+
__PLUGIN_NAME__: pluginName,
|
|
115
|
+
__PLUGIN_SLUG__: slug,
|
|
116
|
+
__PLUGIN_CLASS__: pluginClass,
|
|
117
|
+
__RUNTIME_TYPE__: "cpp",
|
|
118
|
+
});
|
|
119
|
+
}
|
|
72
120
|
} else {
|
|
73
|
-
//
|
|
74
|
-
if (existsSync(resolve(root, "ros2_ws"))) {
|
|
75
|
-
log.warn("
|
|
121
|
+
// → python. Leave any ros2_ws/ or cpp/ in place (never delete user code).
|
|
122
|
+
if (existsSync(resolve(root, "ros2_ws")) || existsSync(resolve(root, "cpp"))) {
|
|
123
|
+
log.warn("existing backend dir left in place (not deleted). Remove it manually if unused.");
|
|
76
124
|
}
|
|
77
125
|
}
|
|
78
126
|
|
|
79
|
-
json.runtime =
|
|
127
|
+
json.runtime = runtimeForChoice(runtimeChoice, slug);
|
|
80
128
|
writeFileSync(path, JSON.stringify(json, null, 2) + "\n");
|
|
81
129
|
log.ok(`${basename(root)} type: ${current} → ${to}`);
|
|
130
|
+
if (isCpp(to)) await prepareCppIde(root, runtimeChoice);
|
|
131
|
+
|
|
132
|
+
if (isCpp(current) !== isCpp(to)) {
|
|
133
|
+
await offerReadme(root, isCpp(to), args.includes("--readme"), {
|
|
134
|
+
__PLUGIN_ID__: pluginId,
|
|
135
|
+
__PLUGIN_NAME__: pluginName,
|
|
136
|
+
__PLUGIN_DIR__: dir,
|
|
137
|
+
__PLUGIN_SLUG__: slug,
|
|
138
|
+
__PLUGIN_CLASS__: pluginClass,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
82
141
|
}
|