Full Code of avwo/whistle for AI

master e5ce148762b9 cached
837 files
5.0 MB
1.3M tokens
3131 symbols
1 requests
Download .txt
Showing preview only (5,343K chars total). Download the full file or copy to clipboard to get everything.
Repository: avwo/whistle
Branch: master
Commit: e5ce148762b9
Files: 837
Total size: 5.0 MB

Directory structure:
gitextract_av_3ek6z/

├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc
├── .gitattributes
├── .gitignore
├── .npmignore
├── .travis.yml
├── CHANGELOG-en_US.md
├── CHANGELOG.md
├── LICENSE
├── README-en_US.md
├── README.md
├── assets/
│   ├── fiddler/
│   │   └── meta.xml
│   ├── js/
│   │   ├── log.js
│   │   ├── weinre.js
│   │   └── worker.js
│   ├── menu.html
│   ├── modal.html
│   └── tab.html
├── bin/
│   ├── ca/
│   │   ├── cli.js
│   │   ├── index.d.ts
│   │   └── index.js
│   ├── import.js
│   ├── plugin.d.ts
│   ├── plugin.js
│   ├── proxy.js
│   ├── status.js
│   ├── use.js
│   ├── util.js
│   └── whistle.js
├── biz/
│   ├── index.js
│   ├── init.js
│   ├── webui/
│   │   ├── cgi-bin/
│   │   │   ├── abort.js
│   │   │   ├── add-rules-values.js
│   │   │   ├── certs/
│   │   │   │   ├── active.js
│   │   │   │   ├── all.js
│   │   │   │   ├── remove.js
│   │   │   │   └── upload.js
│   │   │   ├── check-update.js
│   │   │   ├── cookies.js
│   │   │   ├── create-cert.js
│   │   │   ├── custom-frames.js
│   │   │   ├── custom-handler.js
│   │   │   ├── do-not-show-again.js
│   │   │   ├── download.js
│   │   │   ├── enable-http2.js
│   │   │   ├── get-cert.js
│   │   │   ├── get-custom-certs-files.js
│   │   │   ├── get-custom-certs-info.js
│   │   │   ├── get-data.js
│   │   │   ├── get-frames.js
│   │   │   ├── get-session.js
│   │   │   ├── hide-https-connects.js
│   │   │   ├── https-status.js
│   │   │   ├── import-remote.js
│   │   │   ├── init.js
│   │   │   ├── intercept-https-connects.js
│   │   │   ├── log/
│   │   │   │   └── set.js
│   │   │   ├── plugins/
│   │   │   │   ├── add-registry.js
│   │   │   │   ├── disable-all-plugins.js
│   │   │   │   ├── disable-plugin.js
│   │   │   │   ├── get-plugins.js
│   │   │   │   ├── is-enable.js
│   │   │   │   ├── registry-list.js
│   │   │   │   ├── uninstall.js
│   │   │   │   └── update-rules.js
│   │   │   ├── reset-local-address.js
│   │   │   ├── rootca.js
│   │   │   ├── rules/
│   │   │   │   ├── account.js
│   │   │   │   ├── add.js
│   │   │   │   ├── allow-multiple-choice.js
│   │   │   │   ├── disable-all-rules.js
│   │   │   │   ├── disable-default.js
│   │   │   │   ├── enable-back-rules-first.js
│   │   │   │   ├── enable-default.js
│   │   │   │   ├── enabled.js
│   │   │   │   ├── export.js
│   │   │   │   ├── import.js
│   │   │   │   ├── index.js
│   │   │   │   ├── list.js
│   │   │   │   ├── list2.js
│   │   │   │   ├── move-to.js
│   │   │   │   ├── project.js
│   │   │   │   ├── recycle/
│   │   │   │   │   ├── list.js
│   │   │   │   │   ├── remove.js
│   │   │   │   │   └── view.js
│   │   │   │   ├── remove.js
│   │   │   │   ├── rename.js
│   │   │   │   ├── select.js
│   │   │   │   ├── set-sys-hosts.js
│   │   │   │   └── unselect.js
│   │   │   ├── server-info.js
│   │   │   ├── set-custom-column.js
│   │   │   ├── set-dns-order.js
│   │   │   ├── socket/
│   │   │   │   ├── abort.js
│   │   │   │   ├── change-status.js
│   │   │   │   └── data.js
│   │   │   ├── status.js
│   │   │   ├── top.js
│   │   │   ├── util.js
│   │   │   └── values/
│   │   │       ├── add.js
│   │   │       ├── export.js
│   │   │       ├── get.js
│   │   │       ├── import.js
│   │   │       ├── index.js
│   │   │       ├── list.js
│   │   │       ├── list2.js
│   │   │       ├── move-to.js
│   │   │       ├── recycle/
│   │   │       │   ├── list.js
│   │   │       │   ├── remove.js
│   │   │       │   └── view.js
│   │   │       ├── remove.js
│   │   │       ├── rename.js
│   │   │       └── value.js
│   │   ├── htdocs/
│   │   │   ├── editor.html
│   │   │   ├── index.html
│   │   │   ├── js/
│   │   │   │   ├── decode.js
│   │   │   │   └── index.js
│   │   │   ├── preview.html
│   │   │   └── src/
│   │   │       ├── css/
│   │   │       │   ├── about.css
│   │   │       │   ├── base.css
│   │   │       │   ├── btn-group.css
│   │   │       │   ├── certs.css
│   │   │       │   ├── composer.css
│   │   │       │   ├── context-menu.css
│   │   │       │   ├── detail.css
│   │   │       │   ├── divider.css
│   │   │       │   ├── dropdown.css
│   │   │       │   ├── editor-settings.css
│   │   │       │   ├── editor.css
│   │   │       │   ├── files-dialog.css
│   │   │       │   ├── filter-input.css
│   │   │       │   ├── frames.css
│   │   │       │   ├── iframe-dialog.css
│   │   │       │   ├── iframe.css
│   │   │       │   ├── image-view.css
│   │   │       │   ├── import-dialog.css
│   │   │       │   ├── index.css
│   │   │       │   ├── json-viewer.css
│   │   │       │   ├── kv.css
│   │   │       │   ├── large-dialog.css
│   │   │       │   ├── list-dialog.css
│   │   │       │   ├── list.css
│   │   │       │   ├── menu-item.css
│   │   │       │   ├── message.css
│   │   │       │   ├── modal.css
│   │   │       │   ├── network-settings.css
│   │   │       │   ├── online.css
│   │   │       │   ├── override.css
│   │   │       │   ├── overview.css
│   │   │       │   ├── plugins-mgr.css
│   │   │       │   ├── plugins.css
│   │   │       │   ├── properties.css
│   │   │       │   ├── props-editor.css
│   │   │       │   ├── record-btn.css
│   │   │       │   ├── req-data.css
│   │   │       │   ├── req-detail.css
│   │   │       │   ├── res-detail.css
│   │   │       │   ├── service.css
│   │   │       │   ├── sync-dialog.css
│   │   │       │   ├── table.css
│   │   │       │   ├── textarea.css
│   │   │       │   ├── theme.css
│   │   │       │   ├── timeline.css
│   │   │       │   └── tools.css
│   │   │       ├── js/
│   │   │       │   ├── about.js
│   │   │       │   ├── base-css.js
│   │   │       │   ├── bridge.js
│   │   │       │   ├── btn-group.js
│   │   │       │   ├── certs-info-dialog.js
│   │   │       │   ├── cgi.js
│   │   │       │   ├── close-btn.js
│   │   │       │   ├── columns.js
│   │   │       │   ├── components/
│   │   │       │   │   ├── json/
│   │   │       │   │   │   ├── index.js
│   │   │       │   │   │   ├── parse.js
│   │   │       │   │   │   └── stringify.js
│   │   │       │   │   └── react-json-tree/
│   │   │       │   │       ├── ItemRange.js
│   │   │       │   │       ├── JSONArrayNode.js
│   │   │       │   │       ├── JSONArrow.js
│   │   │       │   │       ├── JSONIterableNode.js
│   │   │       │   │       ├── JSONNestedNode.js
│   │   │       │   │       ├── JSONNode.js
│   │   │       │   │       ├── JSONObjectNode.js
│   │   │       │   │       ├── JSONValueNode.js
│   │   │       │   │       ├── createStylingFromTheme.js
│   │   │       │   │       ├── getCollectionEntries.js
│   │   │       │   │       ├── index.js
│   │   │       │   │       ├── objType.js
│   │   │       │   │       ├── themes/
│   │   │       │   │       │   └── solarized.js
│   │   │       │   │       └── utils/
│   │   │       │   │           └── hexToRgb.js
│   │   │       │   ├── composer-list.js
│   │   │       │   ├── composer.js
│   │   │       │   ├── console.js
│   │   │       │   ├── context-menu.js
│   │   │       │   ├── cookies-dialog.js
│   │   │       │   ├── copy-btn.js
│   │   │       │   ├── data-center.js
│   │   │       │   ├── decode.js
│   │   │       │   ├── detail.js
│   │   │       │   ├── dialog.js
│   │   │       │   ├── divider.js
│   │   │       │   ├── dns-servers-dialog.js
│   │   │       │   ├── dropdown.js
│   │   │       │   ├── editor-dialog.js
│   │   │       │   ├── editor-settings.js
│   │   │       │   ├── editor.js
│   │   │       │   ├── empty.js
│   │   │       │   ├── enable-https-btn.js
│   │   │       │   ├── enabled-rules.js
│   │   │       │   ├── events.js
│   │   │       │   ├── expand-collapse.js
│   │   │       │   ├── export-dialog.js
│   │   │       │   ├── filter-btn.js
│   │   │       │   ├── filter-input.js
│   │   │       │   ├── forward-back-btn.js
│   │   │       │   ├── frame-composer.js
│   │   │       │   ├── frame-data.js
│   │   │       │   ├── frame-list.js
│   │   │       │   ├── frame-modal.js
│   │   │       │   ├── frames.js
│   │   │       │   ├── github-icon.js
│   │   │       │   ├── help-icon.js
│   │   │       │   ├── history-data.js
│   │   │       │   ├── https-settings.js
│   │   │       │   ├── icon.js
│   │   │       │   ├── iframe-dialog.js
│   │   │       │   ├── iframe.js
│   │   │       │   ├── iframes.js
│   │   │       │   ├── image-view.js
│   │   │       │   ├── import-dialog.js
│   │   │       │   ├── index.js
│   │   │       │   ├── inspector.js
│   │   │       │   ├── inspectors.js
│   │   │       │   ├── is-utf8.js
│   │   │       │   ├── json-dialog.js
│   │   │       │   ├── json-viewer.js
│   │   │       │   ├── kv-dialog.js
│   │   │       │   ├── large-dialog.js
│   │   │       │   ├── lazy-init.js
│   │   │       │   ├── list-dialog.js
│   │   │       │   ├── list-modal.js
│   │   │       │   ├── list.js
│   │   │       │   ├── menu-item.js
│   │   │       │   ├── message.js
│   │   │       │   ├── mock-dialog.js
│   │   │       │   ├── modal.js
│   │   │       │   ├── network-modal.js
│   │   │       │   ├── network-settings.js
│   │   │       │   ├── network.js
│   │   │       │   ├── online.js
│   │   │       │   ├── order-table.js
│   │   │       │   ├── overview.js
│   │   │       │   ├── panel-tips.js
│   │   │       │   ├── parse-curl.js
│   │   │       │   ├── parse-rules.js
│   │   │       │   ├── plugins-mgr.js
│   │   │       │   ├── plugins-tabs.js
│   │   │       │   ├── plugins.js
│   │   │       │   ├── properties.js
│   │   │       │   ├── props-editor.js
│   │   │       │   ├── protocols.js
│   │   │       │   ├── qrcode-dialog.js
│   │   │       │   ├── qrcode.js
│   │   │       │   ├── record-btn.js
│   │   │       │   ├── recycle-bin.js
│   │   │       │   ├── req-data.js
│   │   │       │   ├── req-detail.js
│   │   │       │   ├── res-detail.js
│   │   │       │   ├── rule-list.js
│   │   │       │   ├── rules-dialog.js
│   │   │       │   ├── rules-hint.js
│   │   │       │   ├── rules-mode.js
│   │   │       │   ├── saved.js
│   │   │       │   ├── server-log.js
│   │   │       │   ├── service-btn.js
│   │   │       │   ├── service-dialog.js
│   │   │       │   ├── share-via-url-btn.js
│   │   │       │   ├── shortcuts-settings.js
│   │   │       │   ├── storage.js
│   │   │       │   ├── sync-dialog.js
│   │   │       │   ├── tab-frame.js
│   │   │       │   ├── tab-mgr.js
│   │   │       │   ├── table.js
│   │   │       │   ├── tabs.js
│   │   │       │   ├── teleport.js
│   │   │       │   ├── text-dialog.js
│   │   │       │   ├── textarea.js
│   │   │       │   ├── textview.js
│   │   │       │   ├── timeline.js
│   │   │       │   ├── tips-dialog.js
│   │   │       │   ├── tool-box.js
│   │   │       │   ├── tools.js
│   │   │       │   ├── update-all-btn.js
│   │   │       │   ├── util.js
│   │   │       │   ├── view-inspector.js
│   │   │       │   ├── win.js
│   │   │       │   └── workers.js
│   │   │       └── webpack.config.js
│   │   ├── htdocs.js
│   │   └── lib/
│   │       ├── index.js
│   │       └── proxy.js
│   └── weinre/
│       ├── index.js
│       └── server.js
├── docs/
│   ├── .vitepress/
│   │   └── config.mts
│   ├── docs/
│   │   ├── cli.md
│   │   ├── extensions/
│   │   │   ├── dev.md
│   │   │   ├── npm.md
│   │   │   └── usage.md
│   │   ├── faq.md
│   │   ├── getting-started.md
│   │   ├── gui/
│   │   │   ├── composer.md
│   │   │   ├── console.md
│   │   │   ├── https.md
│   │   │   ├── network.md
│   │   │   ├── online.md
│   │   │   ├── plugins.md
│   │   │   ├── rules.md
│   │   │   ├── shortcut.md
│   │   │   ├── values.md
│   │   │   └── weinre.md
│   │   ├── index.md
│   │   ├── mobile.md
│   │   └── rules/
│   │       ├── @.md
│   │       ├── attachment.md
│   │       ├── auth.md
│   │       ├── cache.md
│   │       ├── cipher.md
│   │       ├── cssAppend.md
│   │       ├── cssBody.md
│   │       ├── cssPrepend.md
│   │       ├── delete.md
│   │       ├── disable.md
│   │       ├── enable.md
│   │       ├── excludeFilter.md
│   │       ├── file.md
│   │       ├── filters.md
│   │       ├── forwardedFor.md
│   │       ├── frameScript.md
│   │       ├── headerReplace.md
│   │       ├── host.md
│   │       ├── htmlAppend.md
│   │       ├── htmlBody.md
│   │       ├── htmlPrepend.md
│   │       ├── http.md
│   │       ├── https-proxy.md
│   │       ├── https.md
│   │       ├── ignore.md
│   │       ├── includeFilter.md
│   │       ├── inherit.md
│   │       ├── jsAppend.md
│   │       ├── jsBody.md
│   │       ├── jsPrepend.md
│   │       ├── lineProps.md
│   │       ├── locationHref.md
│   │       ├── log.md
│   │       ├── method.md
│   │       ├── operation.md
│   │       ├── pac.md
│   │       ├── pathReplace.md
│   │       ├── pattern.md
│   │       ├── pipe.md
│   │       ├── plugin-vars.md
│   │       ├── protocols.md
│   │       ├── proxy.md
│   │       ├── rawfile.md
│   │       ├── redirect.md
│   │       ├── referer.md
│   │       ├── replaceStatus.md
│   │       ├── reqAppend.md
│   │       ├── reqBody.md
│   │       ├── reqCharset.md
│   │       ├── reqCookies.md
│   │       ├── reqCors.md
│   │       ├── reqDelay.md
│   │       ├── reqHeaders.md
│   │       ├── reqMerge.md
│   │       ├── reqPrepend.md
│   │       ├── reqReplace.md
│   │       ├── reqRules.md
│   │       ├── reqScript.md
│   │       ├── reqSpeed.md
│   │       ├── reqType.md
│   │       ├── reqWrite.md
│   │       ├── reqWriteRaw.md
│   │       ├── resAppend.md
│   │       ├── resBody.md
│   │       ├── resCharset.md
│   │       ├── resCookies.md
│   │       ├── resCors.md
│   │       ├── resDelay.md
│   │       ├── resHeaders.md
│   │       ├── resMerge.md
│   │       ├── resPrepend.md
│   │       ├── resReplace.md
│   │       ├── resRules.md
│   │       ├── resScript.md
│   │       ├── resSpeed.md
│   │       ├── resType.md
│   │       ├── resWrite.md
│   │       ├── resWriteRaw.md
│   │       ├── responseFor.md
│   │       ├── rule.md
│   │       ├── skip.md
│   │       ├── sniCallback.md
│   │       ├── socks.md
│   │       ├── statusCode.md
│   │       ├── style.md
│   │       ├── tpl.md
│   │       ├── trailers.md
│   │       ├── tunnel.md
│   │       ├── ua.md
│   │       ├── urlParams.md
│   │       ├── weinre.md
│   │       ├── ws.md
│   │       ├── wss.md
│   │       ├── xfile.md
│   │       ├── xhost.md
│   │       ├── xhttps-proxy.md
│   │       ├── xproxy.md
│   │       ├── xrawfile.md
│   │       ├── xsocks.md
│   │       └── xtpl.md
│   ├── en/
│   │   ├── docs/
│   │   │   ├── cli.md
│   │   │   ├── extensions/
│   │   │   │   ├── dev.md
│   │   │   │   ├── npm.md
│   │   │   │   └── usage.md
│   │   │   ├── faq.md
│   │   │   ├── getting-started.md
│   │   │   ├── gui/
│   │   │   │   ├── composer.md
│   │   │   │   ├── console.md
│   │   │   │   ├── https.md
│   │   │   │   ├── network.md
│   │   │   │   ├── online.md
│   │   │   │   ├── plugins.md
│   │   │   │   ├── rules.md
│   │   │   │   ├── shortcut.md
│   │   │   │   ├── values.md
│   │   │   │   └── weinre.md
│   │   │   ├── index.md
│   │   │   ├── mobile.md
│   │   │   └── rules/
│   │   │       ├── @.md
│   │   │       ├── attachment.md
│   │   │       ├── auth.md
│   │   │       ├── cache.md
│   │   │       ├── cipher.md
│   │   │       ├── cssAppend.md
│   │   │       ├── cssBody.md
│   │   │       ├── cssPrepend.md
│   │   │       ├── delete.md
│   │   │       ├── disable.md
│   │   │       ├── enable.md
│   │   │       ├── excludeFilter.md
│   │   │       ├── file.md
│   │   │       ├── filters.md
│   │   │       ├── forwardedFor.md
│   │   │       ├── frameScript.md
│   │   │       ├── headerReplace.md
│   │   │       ├── host.md
│   │   │       ├── htmlAppend.md
│   │   │       ├── htmlBody.md
│   │   │       ├── htmlPrepend.md
│   │   │       ├── http.md
│   │   │       ├── https-proxy.md
│   │   │       ├── https.md
│   │   │       ├── ignore.md
│   │   │       ├── includeFilter.md
│   │   │       ├── inherit.md
│   │   │       ├── jsAppend.md
│   │   │       ├── jsBody.md
│   │   │       ├── jsPrepend.md
│   │   │       ├── lineProps.md
│   │   │       ├── locationHref.md
│   │   │       ├── log.md
│   │   │       ├── method.md
│   │   │       ├── operation.md
│   │   │       ├── pac.md
│   │   │       ├── pathReplace.md
│   │   │       ├── pattern.md
│   │   │       ├── pipe.md
│   │   │       ├── plugin-vars.md
│   │   │       ├── protocols.md
│   │   │       ├── proxy.md
│   │   │       ├── rawfile.md
│   │   │       ├── redirect.md
│   │   │       ├── referer.md
│   │   │       ├── replaceStatus.md
│   │   │       ├── reqAppend.md
│   │   │       ├── reqBody.md
│   │   │       ├── reqCharset.md
│   │   │       ├── reqCookies.md
│   │   │       ├── reqCors.md
│   │   │       ├── reqDelay.md
│   │   │       ├── reqHeaders.md
│   │   │       ├── reqMerge.md
│   │   │       ├── reqPrepend.md
│   │   │       ├── reqReplace.md
│   │   │       ├── reqRules.md
│   │   │       ├── reqScript.md
│   │   │       ├── reqSpeed.md
│   │   │       ├── reqType.md
│   │   │       ├── reqWrite.md
│   │   │       ├── reqWriteRaw.md
│   │   │       ├── resAppend.md
│   │   │       ├── resBody.md
│   │   │       ├── resCharset.md
│   │   │       ├── resCookies.md
│   │   │       ├── resCors.md
│   │   │       ├── resDelay.md
│   │   │       ├── resHeaders.md
│   │   │       ├── resMerge.md
│   │   │       ├── resPrepend.md
│   │   │       ├── resReplace.md
│   │   │       ├── resRules.md
│   │   │       ├── resScript.md
│   │   │       ├── resSpeed.md
│   │   │       ├── resType.md
│   │   │       ├── resWrite.md
│   │   │       ├── resWriteRaw.md
│   │   │       ├── responseFor.md
│   │   │       ├── rule.md
│   │   │       ├── skip.md
│   │   │       ├── sniCallback.md
│   │   │       ├── socks.md
│   │   │       ├── statusCode.md
│   │   │       ├── style.md
│   │   │       ├── tpl.md
│   │   │       ├── trailers.md
│   │   │       ├── tunnel.md
│   │   │       ├── ua.md
│   │   │       ├── urlParams.md
│   │   │       ├── weinre.md
│   │   │       ├── ws.md
│   │   │       ├── wss.md
│   │   │       ├── xfile.md
│   │   │       ├── xhost.md
│   │   │       ├── xhttps-proxy.md
│   │   │       ├── xproxy.md
│   │   │       ├── xrawfile.md
│   │   │       ├── xsocks.md
│   │   │       └── xtpl.md
│   │   └── index.md
│   └── index.md
├── index.d.ts
├── index.js
├── lib/
│   ├── config.js
│   ├── handlers/
│   │   ├── error-handler.js
│   │   ├── file-proxy.js
│   │   ├── http-proxy.js
│   │   └── index.js
│   ├── https/
│   │   ├── ca.js
│   │   ├── h2.js
│   │   ├── index.js
│   │   └── load-cert.js
│   ├── index.js
│   ├── init.js
│   ├── inspectors/
│   │   ├── data.js
│   │   ├── index.js
│   │   ├── log.js
│   │   ├── req.js
│   │   ├── res.js
│   │   ├── rules.js
│   │   └── weinre.js
│   ├── plugins/
│   │   ├── compat.js
│   │   ├── get-plugins-sync.js
│   │   ├── get-plugins.js
│   │   ├── index.js
│   │   ├── load-plugin.js
│   │   ├── module-paths.js
│   │   ├── proxy.js
│   │   ├── shared-storage.js
│   │   └── util.js
│   ├── rules/
│   │   ├── dns.js
│   │   ├── index.js
│   │   ├── protocols.js
│   │   ├── recycle-bin.js
│   │   ├── rules.js
│   │   ├── storage.js
│   │   └── util.js
│   ├── service/
│   │   ├── compose-data.js
│   │   ├── composer.js
│   │   ├── data-center.js
│   │   ├── extract-saz.js
│   │   ├── generate-saz.js
│   │   ├── index.js
│   │   ├── install.js
│   │   ├── service.js
│   │   └── util.js
│   ├── socket-mgr.js
│   ├── tunnel.js
│   ├── upgrade.js
│   └── util/
│       ├── common.js
│       ├── data-server.js
│       ├── drain.js
│       ├── file-mgr.js
│       ├── file-writer-transform.js
│       ├── http-mgr.js
│       ├── index.js
│       ├── is-utf8.js
│       ├── log-server.js
│       ├── logger.js
│       ├── parse-query.js
│       ├── parse-url-safe.js
│       ├── parse-url.js
│       ├── patch.js
│       ├── perf.js
│       ├── process.js
│       ├── replace-pattern-transform.js
│       ├── replace-string-transform.js
│       ├── speed-transform.js
│       ├── transproto.js
│       ├── whistle-transform.js
│       └── zlib.js
├── package.json
├── require.js
└── test/
    ├── assets/
    │   ├── certs/
    │   │   ├── _.cert.w2.org.crt
    │   │   ├── _.cert.w2.org.key
    │   │   ├── _root.crt
    │   │   ├── cert.w2.org.key
    │   │   ├── root.key
    │   │   ├── test.crt
    │   │   └── test.key
    │   ├── files/
    │   │   ├── 1.txt
    │   │   ├── 2.txt
    │   │   ├── 3.txt
    │   │   ├── empty.txt
    │   │   ├── gb2312.txt
    │   │   ├── mock-remote-key.txt
    │   │   ├── mock-script-key.txt
    │   │   ├── rules.txt
    │   │   ├── service-remote-key.txt
    │   │   ├── service-script-key.txt
    │   │   ├── shadow-remote-key.txt
    │   │   ├── shadow-script-key.txt
    │   │   ├── storage/
    │   │   │   ├── .backup/
    │   │   │   │   ├── 1.test1.tx
    │   │   │   │   ├── 2.test2.tx
    │   │   │   │   ├── 3.test3.tx
    │   │   │   │   └── properties
    │   │   │   ├── files/
    │   │   │   │   ├── 1.test1.tx
    │   │   │   │   ├── 2.test2.tx
    │   │   │   │   └── 3.test3.tx
    │   │   │   └── properties
    │   │   └── test.txt
    │   ├── rules/
    │   │   ├── mock.txt
    │   │   ├── service.txt
    │   │   └── shadow.txt
    │   └── values/
    │       ├── json5.txt
    │       ├── rawFile.html
    │       ├── rawFile2.js
    │       ├── reqScript.js
    │       ├── resScript.js
    │       ├── rulesFile.js
    │       ├── rulesFile.txt
    │       ├── rulesFile2.js
    │       ├── test.json
    │       ├── test.txt
    │       ├── test2.json
    │       ├── test3.json
    │       ├── tps.rules
    │       ├── tps1.json
    │       └── tps2.json
    ├── config.test.js
    ├── events.js
    ├── index.test.js
    ├── plugins/
    │   ├── @test/
    │   │   └── whistle.test3/
    │   │       ├── index.js
    │   │       ├── package.json
    │   │       ├── rules.txt
    │   │       └── test/
    │   │           └── abc/
    │   │               ├── abc/
    │   │               │   └── index.html
    │   │               └── index.html
    │   ├── whistle.pass/
    │   │   ├── index.js
    │   │   └── package.json
    │   ├── whistle.pipe-http/
    │   │   ├── index.js
    │   │   ├── lib/
    │   │   │   ├── assert.js
    │   │   │   ├── reqReadServer.js
    │   │   │   ├── reqWriteServer.js
    │   │   │   ├── resReadServer.js
    │   │   │   └── resWriteServer.js
    │   │   ├── package.json
    │   │   └── rules.txt
    │   ├── whistle.pipe-tunnel/
    │   │   ├── index.js
    │   │   ├── lib/
    │   │   │   ├── assert.js
    │   │   │   ├── tunnelReqRead.js
    │   │   │   ├── tunnelReqWrite.js
    │   │   │   ├── tunnelResRead.js
    │   │   │   └── tunnelResWrite.js
    │   │   ├── package.json
    │   │   └── rules.txt
    │   ├── whistle.pipe-ws/
    │   │   ├── index.js
    │   │   ├── lib/
    │   │   │   ├── assert.js
    │   │   │   ├── wsReqRead.js
    │   │   │   ├── wsReqWrite.js
    │   │   │   ├── wsResRead.js
    │   │   │   └── wsResWrite.js
    │   │   ├── package.json
    │   │   └── rules.txt
    │   ├── whistle.test/
    │   │   ├── _rules.txt
    │   │   ├── assets/
    │   │   │   ├── dispatch.js
    │   │   │   ├── files/
    │   │   │   │   ├── append.txt
    │   │   │   │   ├── bin/
    │   │   │   │   │   ├── body.txt
    │   │   │   │   │   ├── bottom.txt
    │   │   │   │   │   ├── file.txt
    │   │   │   │   │   └── top.txt
    │   │   │   │   ├── body.txt
    │   │   │   │   ├── css.css
    │   │   │   │   ├── html.html
    │   │   │   │   ├── index.html
    │   │   │   │   ├── js.js
    │   │   │   │   ├── log.js
    │   │   │   │   ├── pac.js
    │   │   │   │   ├── prepend.txt
    │   │   │   │   ├── rawfile.html
    │   │   │   │   ├── ssi-include.html
    │   │   │   │   ├── ssi1.html
    │   │   │   │   ├── ssi2.html
    │   │   │   │   ├── ssi3.html
    │   │   │   │   └── tpl.js
    │   │   │   └── values/
    │   │   │       ├── headers.json
    │   │   │       ├── replace.json
    │   │   │       ├── req.json
    │   │   │       ├── reqCookies.json
    │   │   │       ├── reqCors.json
    │   │   │       ├── res.json
    │   │   │       ├── resCookies.json
    │   │   │       ├── resCors.json
    │   │   │       ├── upload.json
    │   │   │       ├── urlParams.json
    │   │   │       └── urlReplace.json
    │   │   ├── index.js
    │   │   ├── lib/
    │   │   │   ├── resRulesServer.js
    │   │   │   ├── rulesServer.js
    │   │   │   ├── server.js
    │   │   │   ├── statusServer.js
    │   │   │   ├── tunnelRulesServer.js
    │   │   │   ├── tunnelServer.js
    │   │   │   ├── uiServer.js
    │   │   │   └── util.js
    │   │   ├── package.json
    │   │   └── rules.txt
    │   ├── whistle.test-values/
    │   │   ├── index.js
    │   │   ├── package.json
    │   │   └── rules.txt
    │   ├── whistle.test1/
    │   │   ├── _rules.txt
    │   │   ├── index.js
    │   │   ├── lib/
    │   │   │   └── rulesServer.js
    │   │   ├── package.json
    │   │   └── rules.txt
    │   └── whistle.test2/
    │       ├── _rules.txt
    │       ├── index.js
    │       ├── package.json
    │       ├── rules.txt
    │       └── test.txt
    ├── proxy/
    │   ├── disable.test.js
    │   └── enable.test.js
    ├── rules.txt
    ├── units/
    │   ├── _normalizeConnectArgs.test.js
    │   ├── attachment.test.js
    │   ├── auth.test.js
    │   ├── cache.test.js
    │   ├── common.test.js
    │   ├── composer.test.js
    │   ├── connect.test.js
    │   ├── css.test.js
    │   ├── delete.test.js
    │   ├── disable.test.js
    │   ├── file.test.js
    │   ├── filter.test.js
    │   ├── fm.test.js
    │   ├── forward.test.js
    │   ├── host.test.js
    │   ├── html.test.js
    │   ├── https.test.js
    │   ├── ignore.test.js
    │   ├── insertFile.test.js
    │   ├── js.test.js
    │   ├── keys.test.js
    │   ├── log.test.js
    │   ├── method.test.js
    │   ├── options.test.js
    │   ├── others.test.js
    │   ├── pac.test.js
    │   ├── params.test.js
    │   ├── plugin.test.js
    │   ├── plugins.test.js
    │   ├── proxy.test.js
    │   ├── range.test.js
    │   ├── rawfile.test.js
    │   ├── redirect.test.js
    │   ├── referer.test.js
    │   ├── replaceStatus.test.js
    │   ├── req.prepend.body.append.test.js
    │   ├── reqAppend.test.js
    │   ├── reqBody.test.js
    │   ├── reqCharset.test.js
    │   ├── reqCookies.test.js
    │   ├── reqCors.test.js
    │   ├── reqDelay.test.js
    │   ├── reqHeaders.test.js
    │   ├── reqPrepend.test.js
    │   ├── reqReplace.test.js
    │   ├── reqSpeed.test.js
    │   ├── reqType.test.js
    │   ├── res.prepend.body.append.test.js
    │   ├── resAppend.test.js
    │   ├── resBody.test.js
    │   ├── resCharset.test.js
    │   ├── resCookies.test.js
    │   ├── resCors.test.js
    │   ├── resDelay.test.js
    │   ├── resHeaders.test.js
    │   ├── resPrepend.test.js
    │   ├── resReplace.test.js
    │   ├── resSpeed.test.js
    │   ├── resType.test.js
    │   ├── rule.test.js
    │   ├── rulesFile.test.js
    │   ├── script.test.js
    │   ├── socks.test.js
    │   ├── ssi-include.test.js
    │   ├── statusCode.test.js
    │   ├── tpl.test.js
    │   ├── tplStr.test.js
    │   ├── tps.test.js
    │   ├── tunnel.test.js
    │   ├── tunnelPolicy.test.js
    │   ├── ua.test.js
    │   ├── ui.test.js
    │   ├── urlParams.test.js
    │   ├── urlReplace.test.js
    │   ├── utils.test.js
    │   ├── values.test.js
    │   ├── var.test.js
    │   ├── weinre.test.js
    │   ├── wildcard.test.js
    │   ├── write.test.js
    │   ├── ws.test.js
    │   └── xfile.test.js
    └── util.test.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .babelrc
================================================
{
  "presets": [
    "env",
    "react"
  ],
  "plugins": [
    "transform-class-properties",
    "transform-object-rest-spread"
  ],
  "ignore": [
    "./biz/webui/htdocs/src/js/components/json/eval.js"
  ]
}


================================================
FILE: .editorconfig
================================================
# http://editorconfig.org
root = true

[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
max_line_length = 80
trim_trailing_whitespace = true

[*.md]
max_line_length = 0
trim_trailing_whitespace = false

[COMMIT_EDITMSG]
max_line_length = 0

================================================
FILE: .eslintignore
================================================
node_modules
/biz/webui/htdocs/js
/biz/webui/htdocs/src/js/components
/test/assets/values
/test/plugins/whistle.test/assets
/bin/import.js
/test/all_whistles


================================================
FILE: .eslintrc
================================================
{
  "env": {
    "browser": true,
    "node": true,
    "es6": true
  },
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended"
  ],
  "parser": "babel-eslint",
  "parserOptions": {
    "ecmaFeatures": {
      "experimentalObjectRestSpread": true,
      "jsx": true
    }
  },
  "plugins": [
    "react"
  ],
  "rules": {
    "indent": [
      "error",
      2
    ],
    "react/display-name": 0,
    "react/prop-types": 0,
    "react/no-direct-mutation-state": 0,
    "linebreak-style": [
      "error",
      "unix"
    ],
    "quotes": [
      "error",
      "single"
    ],
    "semi": [
      "error",
      "always"
    ],
    "no-unused-vars": [
      "error",
      {
        "vars": "all",
        "args": "none"
      }
    ],
    "no-empty": [
      "error",
      {
        "allowEmptyCatch": true
      }
    ],
    "no-cond-assign": "off"
  }
}


================================================
FILE: .gitattributes
================================================
biz/webui/htdocs/js/index.js diff=nodiff


================================================
FILE: .gitignore
================================================
# Logs
logs
*.log
.DS_Store
tmp

# Runtime data
pids
*.pid
*.seed

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directory
# Commenting this out is preferred by some people, see
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git-
node_modules

# Users Environment Variables
.lock-wscript

# OS X
.DS_Store*
Icon?
._*



# Windows
Thumbs.db
ehthumbs.db
Desktop.ini

# Linux
.directory
.running
*~


# npm
node_modules
*.log
*.gz


# Coveralls
coverage


# test
/test/.whistle

# docs
_book
dist
/.history
/test/temp_files
/test/all_whistles
/docs/.vitepress/dist
/docs/.vitepress/cache


================================================
FILE: .npmignore
================================================
# Logs
logs
*.log
.DS_Store
tmp

# Runtime data
pids
*.pid
*.seed

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directory
# Commenting this out is preferred by some people, see
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git-
node_modules

# Users Environment Variables
.lock-wscript

# OS X
.DS_Store*
Icon?
._*



# Windows
Thumbs.db
ehthumbs.db
Desktop.ini

# Linux
.directory
.running
*~


# npm
node_modules
*.log
*.gz
.gitignore
.gitattributes
.npmignore
.travis.yml
.eslintrc
.editorconfig
.eslintignore
.babelrc
test
assets/launcher
/biz/webui/htdocs/src
/docs
/.history
CHANGELOG*
Dockerfile
/README-en_US.md
/biz/webui/htdocs/js/decode.js


# Coveralls
coverage


================================================
FILE: .travis.yml
================================================
language: node_js
node_js:
  - "10"
  - "11"
  - "12"
  - "13"
  - "14"
  - "15"
  - "16"
  - "17"
  - "18"

install:
  - npm install

script:
  - npm run cov

after_script:
  - npm i codecov && codecov


================================================
FILE: CHANGELOG-en_US.md
================================================
[中文](./CHANGELOG.md) · English

## v2.10.1
1. fix: https://github.com/avwo/whistle/issues/1296
2. fix: https://github.com/avwo/whistle/issues/1297
3. feat: Quickly filter requests with matching rules

## v2.10.0
1. feat: Move the Raw Tab of Inspectors to the first position.
2. feat: Local mapping paths are not allowed to contain `../` path segments.
3. feat: Allow disabling or enabling custom certificates without deletion.
4. feat: Plugin variable `%plugin-name=xxx` now supports all plugin hooks.
5. refactor: Simplify the code passing mechanism between Whistle and plugins, improving efficiency.
6. fix: Improve test cases and fix hidden bugs.

## v2.9
1. feat: UI and Experience Improvements:
      - Redesigned Dark mode interface according to Dark mode specifications.
      - Network supports filtering by type and manually saving captured packet data.
      - Composer supports importing CURL commands and displaying SSE/WebSocket content.
      - JSON Viewer right-click menu now supports copying selected text.
      - Support for displaying TTFB, SSE content, and WebSocket Frames.
      - Added `frameScript` for modifying WebSocket/TCP request content via JS.
2. feat: Rule and Configuration Enhancements:
     - Support loading default configurations via `~/.whistlerc`.
     - Rules support viewing `Enabled Rules` and grouping functionality.
     - Support setting matching probability: `includeFilter://chance:0.5`.
     - Added `delete://` protocol to delete request parameters, cookies, etc.
     - Support `req.passThrough({transformReq, transformRes, ...})`.
     - Embedded values now have independent scopes (Rules, Plugins, Header Rules are isolated).
3. feat: Plugin System Improvements:
     - Support installing/uninstalling plugins via the UI.
     - Added custom right-click menu to the plugin list.
     - Plugins support `sharedStorage` for data sharing across different instances.
     - Plugin Option pages support setting favicon and opening as dialog boxes.
     - Support installing plugins via plugins.
4. feat: Network and Proxy Features:
     - Enabled `localhostCompatible` mode by default.
     - Support for IPv6-only networks.
     - Support for SOCKS proxy and custom DNS servers.
     - Added `https-proxy` and `internal-http-proxy` protocols.
     - Support for HTTP2 functionality (requires Node 10.16.0+).
5. feat: Certificate and Security:
     - Default certificate format changed to .cer for better compatibility with more devices.
     - Support for custom client certificates and mutual TLS authentication.
     - Root certificates can be updated via `w2 ca` upon expiration.

## v2.8
1. feat: Multi-process Support
      - Added `--cluster [workers]` startup mode, supporting multi-process operation.
      - Fixed an issue where plugin remote rules failed to access when binding to a non-local network interface during startup.
2. feat: Certificate Management Optimization
      - Auto-generated certificates are automatically renewed upon expiration (valid for one year).
      - Prohibited uploading root certificate files (`root.key & root.crt`) via the web interface.
      - Support for non-SNI requests to obtain custom certificates via plugins.
      - Support for directly uploading and deleting user-defined certificates.
3. feat: Plugin System Enhancements
      - Plugin `server` hooks support setting dynamic rules via `req.setReqRules` and `req.setResRules`.
      - Plugins can obtain client connection information (`originalReq.remoteAddress` and `originalReq.remotePort`).
      - Fixed an issue where requests did not re-enter TUNNEL proxy when the plugin `sniCallback` returned `false`.
      - Optimized plugin rule execution: req and res rules are now executed separately.
4. feat: Proxy Rule Enhancements
      - Support filtering `ignore://*` via `ignore://-*`.
      - Support `proxy` and `pac` configurations with `lineProps://proxyHostOnly`, making the proxy effective only when the user configures a `host`.
      - HTTPS Server started with `--httpsPort` can obtain certificates from plugins.
5. feat: Filter Rule Extensions
      - Support filtering requests by source using `excludeFilter://from=httpServer`, `includeFilter://from=httpsServer`, etc.
      - Support modifying the domain or port of log and weinre requests via `enable://useLocalHost` and `enable://useSafePort`.
6. feat: Request Header Control
      - `x-forwarded-host` and `x-forwarded-proto` are disabled by default. They can be enabled via:
      - Startup parameters `-M x-forwarded-host|x-forwarded-proto`.
      - Request header `x-whistle-forwarded-props: host,proto,for,clientIp,ip`.
7. feat: Custom Interface
      - Support custom `inspectors tab`.
      - The interface provides an `api.selectIndex` method to select captured packet data at a specific index.
8. feat: Data Limits and Optimization
      - Default displayed captured packet data is limited to 1.5MB, expandable to 2.5MB via `enable://bigData`.
      - Support setting response rules via request headers.
      - Optimized certificate fetching logic, merging multiple identical requests.
9. File Path Handling
      - Distinct handling of `reqWrite:///path/to/` and `reqWrite:///path/to`, where the former is automatically completed to `index.html`.
10. Merge Operation Enhancement
      - `resMerge://json1 resMerge://json2` uses shallow merge by default; deep merge can be enabled via `resMerge://true`.
11. feat: Force Write Support
      - Support forcing `reqWrite`, `reqWriteRaw`, `resWrite`, and `resWriteRaw` via `enable://forceReqWrite` and `enable://forceResWrite`.
12. feat: Authentication Hook Optimization
     - The plugin's auth hook now applies to resolved HTTPS requests by default.
     - Support enabling the auth hook for tunnel proxy requests via `enable://authCapture`.
13. fix: Issue Fixes
     - Fixed a potential issue where saz files could not be imported.
     - Fixed a memory leak issue in `sniCallback`.
     - Handled `unhandledRejection` events.
14. refactor: Code Optimizations
     - When a plugin receives an HTTPS request, `req.url` will contain the full path.
     - Optimized certificate fetching logic to reduce duplicate requests.
     - Support disabling `enable://abort` via `disable://abort`.

## v2.7

1. feat: HTTP2 Feature Extensions
      - **HTTP2 non-HTTPS Support**: HTTP2 protocol now supports non-HTTPS requests.
      - **Performance Monitoring**: Third-party integrations can obtain runtime data like CPU, memory, request volume via `proxy.on('perfDataChange')`.
2. feat: Comprehensive Plugin System Enhancements
      - **Async Support**: Plugin hooks now support `async-await` syntax.
      - **Authentication Integration**: Plugin `whistleConfig` supports configuring `inheritAuth` to reuse Whistle login accounts.
      - **Plugin Management**: Support automatic loading of the plugin when executing `w2 run` in the plugin's root directory.
      - **Configuration Sharing**: Plugins support obtaining certificates for specified domains via `options.getCert()`.
      - **Dependency Reference**: Plugins can directly reference Whistle internal modules via `options.require`.
3. feat: Command Line Tool Improvements
      - **Configuration Management**: Support loading startup configurations via `--config localFile` (higher priority than command line).
      - **Instance Management**: Optimized `w2 stop` command; displays all running instances when none is found.
      - **Docker Support**: Added Dockerfile to the source directory.
4. feat: DNS Resolution Enhancements
      - **Custom DNS**: Support custom DNS servers via the `--dnsServer` parameter.
      - **DNS over HTTPS**: Support for DNS-over-HTTPS services like `http://dns.alidns.com/resolve`.
      - **IPv6 Support**: Manual specification of IPv6 DNS server addresses is possible.
5. feat: Proxy Protocol Optimizations
      - **PAC Authentication**: `pac` protocol supports setting username and password: `pac://user:pass@pacPath`.
      - **Tunnel Proxy**: Support for plugins setting `tunnelKey` to pass tunnel proxy request headers.
      - **Proxy Forwarding**: Optimized `lineProps://proxyHost|proxyTunnel|proxyFirst` configuration.
6. feat: Request Header Processing
      - **Forwarding Control**: Support disabling specific forwarding headers via `-M disableForwardedHost` and `-M disableForwardedProto`.
      - **Custom Parsing**: `pipe://xxx` supports plugins internally obtaining original rule values.
7. feat: Network View Upgrade
      - **Tree View Support**: Network now supports displaying captured packet data in a tree view.
      - **Raw URL Display**: Support for displaying the original URL (Raw Url).
      - **Data Size Display**: The Body column in Network shows the request content size.
      - **List Optimization**: Fixed data updating and sorting issues in Tree View and List View.
8. feat: Interface Interaction Improvements
      - **Composer History**: Optimized display of Composer history list.
      - **Left Menu**: Optimized left menu layout and interaction.
      - **Status Hints**: More obvious reminders when Rules and Plugins are disabled.
      - **Shortcut Support**: Fixed shortcut key issues in Values right-click menu.
9. feat: Rule Editor Enhancements
      - **Rule Sorting**: Support adding Rules to the top.
      - **Error Handling**: Fixed an error when entering `!` in the Rules editor.
      - **Intelligent Suggestions**: `pipe` protocol now supports intelligent suggestions.
10. feat: Authentication Feature Extensions
        - **Plugin Authentication**: Plugin `auth` method supports `req.setRedirect(url)` for redirection.
        - **Login Box Support**: Plugin `auth` supports setting `req.showLoginBox` to pop up a login box.
        - **Internal Requests**: Plugin `auth` method now supports handling Whistle internal requests.
11. feat: Certificate Management
        - **Root Certificate Management**: Support displaying custom root certificates and deletion guidance.
        - **Remote Certificates**: Support obtaining remote certificates via the plugin `sniCallback(req, options)` hook.
12. feat: Custom Parsers
        - **HTTP Parsing**: Regular HTTP requests now also support `customParser` (or `customFrames`).
        - **Data Replacement**: Fixed inaccurate matching issues in `reqReplace` and `resReplace` due to packet splitting.
13. feat: Protocol Support Extensions
        - **Status Code Replacement**: WebSocket and Tunnel requests support `replaceStatus`.
        - **Console Log Control**: Support preventing `log://` from intercepting `console` via `disable://interceptConsole`.
        - **CORS Handling**: `resCors://enable` automatically ignores when the request header lacks an `origin`.
14. feat: Memory Optimization
        - **Empty Request Handling**: Removed `Empty Request` to reduce memory and CPU usage.
        - **Stack Overflow Fix**: Fixed "Maximum call stack size exceeded" errors.
        - **Storage Separation**: Plugins use different storage directories in different instances.
15. feat: Startup and Runtime Optimization
        - **Startup Speed**: Optimized Whistle startup speed.
        - **Delay Implementation**: Optimized the implementation mechanism of `reqDelay` and `resDelay`.
        - **Plugin Loading**: Third-party integrations can listen to plugin loading events.
16. feat: Template String Enhancements
        - **Port Variables**: Support obtaining port information via `clientPort` and `serverPort` in template strings.
        - **Plugin Variables**: Support setting multiple `%plugin-name=xxxx` simultaneously in rules (up to 10).
17. fix: Issue Fixes
        - **Dialog Customization**: Browser built-in windows like `alert`, `confirm`, `prompt` now use custom implementations to prevent Chrome restrictions.
        - **WebSocket Capture**: Fixed an issue where WebSocket packets could not be captured.
        - **Plugin Storage**: Fixed an issue where `storage.setProperties` in plugins could fail.
        - **Request Pause**: Fixed response stream pause issues under certain conditions.
        - **Third-party Integration**: Fixed internal request forwarding issues during third-party integrations.
18. feat: Feature Adjustments
        - **Deletion Timing**: Adjusted the execution timing of `delete://reqH.xxxx`.
        - **Forwarding Logic**: Optimized the implementation of internal request forwarding logic.
19. feat: Other Improvements
        - **Rule Mode**: Support setting `-M shadowRules` (capture + set rules) or `-M shadowRulesOnly` (rules only).
        - **UI Requests**: Display UI request status.
        - **Error Messages**: Optimized error messages.
        - **Protocol Display**: Display the HTTP protocol type forwarded by plugins.

## v2.6

1. feat: System Monitoring and Status
      - **Online Status Monitoring**: View current process request count, CPU, and memory status via the `Online` menu.
      - **API Monitoring Interface**: Support obtaining runtime information via `proxy.getRuntimeInfo()`.
      - **Performance Metrics**: The Online panel supports displaying QPS and maximum values of memory, CPU, and QPS.
2. feat: Data Management
      - **Recycle Bin Feature**: Deleted Rules or Values are first moved to the Recycle Bin (up to 120 cached items), with support for recovery.
      - **Certificate Generation Tool**: `Network > Tools > ToolBox` supports generating certificates for corresponding domains.
      - **HAR File Export**: Support exporting captured packet data as HAR format files.
3. feat: Network Feature Enhancements
      - **Advanced Search**: The search box supports filtering with up to 3 keywords.
      - **View Source**: Right-click menu adds `Open/Source` to view captured packet data source code.
      - **SVG Preview**: Support previewing SVG files.
4. feat: Editor and Rule Management
      - **Read-Only Mode**: Support setting Rules & Values editors to read-only mode via the `disabledEditor=1` parameter.
      - **Line Number Comments**: When line numbers are enabled, double-clicking the line number can comment or uncomment.
      - **Rule Highlighting**: Optimized editor highlighting for plugin rules.
5. feat: Interaction Improvements
      - **Toolset Extension**: `Network / Tools / Toolbox` supports converting objects to Query parameters.
      - **Quick Operations**: Support extending the `util.openEditor(value)` method.
6. feat: Rule Import/Export
      - **Rule Import**: Support importing rules into Rules via `--shadowRules jsonString`.
      - **Command Line Output**: Optimized information display when starting from the command line.
7. feat: Mode Settings
      - **Operation Modes**: Support setting multiple modes via the `-M` parameter:
      - `disabledBackOption|disabledMultipleOption|notAllowDisableRules`
      - `rulesOnly` and `pluginsOnly`
8. feat: Internal Path Handling
      - **Path Flexibility**: Internal paths support setting domain and port parameters, formats:
      - `/...whistle-path.5b6af7b9884e1165...///__domain__port__/path/to`
      - `/...whistle-path.5b6af7b9884e1165...///path/to?_whistleInternalHost_=__domain__port__`
9. Memory and Connection Management
      - **Connection Optimization**: Ensure timely closure of unused connections to reduce memory usage.
      - **GC Optimization**: Adjusted GC parameters `--max-semi-space-size=64`.
      - **Performance Monitoring**: Support obtaining the total number of currently processed requests via CGI or API.
10. feat: Exception Handling
        - **Plugin Exceptions**: Support obtaining exception information thrown by plugins via `process.on('pforkError')`.
        - **Uncaught Exceptions**: Optimized handling of uncaught exceptions during request processing.
        - **Timeout Handling**: Added `timeout` event to `onSocketEnd`, compatible with various abnormal situations.
11. feat: Internal Connections
        - **Connection Management**: Optimized internal connection management mechanism.
12. feat: Filter Rules
        - **Rule Fix**: Fixed result disorder when mixing `excludeFilter` and `includeFilter` configurations.
        - **Domain Matching**: Domain wildcards now support obtaining submatch content.
13. feat: Proxy Configuration
        - **Proxy Connection Header**: Support changing the proxy forwarding header to `Proxy-Connection: close` via `disable://proxyConnection`.
        - **Client Filtering**: Support filtering captured packet data via the `clientId` URL parameter.
14. fix: Major Issue Fixes
        - **Rule File Saving**: Fixed an issue where saving failed when rule file names were too long.
        - **Editor Issue**: Fixed an issue with editor highlighting for plugin rules.
        - **Management Interface Security**: Fixed an issue where CGI paths in the management interface could be arbitrarily concatenated.
        - **Node Version Compatibility**: Fixed compatibility issues with specific Node versions (v15.5.0).
        - **pipe Protocol**: Fixed issues that could lead to data loss.
        - **Local File Replacement**: Response headers for local file replacements now include `content-length` by default.
15. perf: Performance Issues
        - **Freeze Issue**: Fixed potential freezes in some Node versions.
        - **Connection Leakage**: Optimized connection management to reduce resource usage.
16. feat: Response Header Handling
        - **Content Length Control**: Local file replacements automatically add the `content-length` field, which can be disabled via `delete://resH.content-length`.
17. Internal Request Handling
        - **Async Handling**: Support listening for plugin process exceptions via `process.on('pforkError')`.

## v2.5

1. feat: Client Certificate Support
      - **Custom Client Certificates**: Support configuring custom client certificates to enhance security authentication.
      - **Connection Error Handling**: Optimized error handling mechanism when establishing connections.
2. feat: Security Protocol Enhancements
      - **Cipher Algorithm Extension**: Added `cipher` protocol to support custom fallback encryption algorithms.
      - **Security Update**: Updated node-forge to address known security issues.
      - **Plugin Security Control**: Startup parameters support controlling plugin loading via `allowPluginList` and `blockPluginList`.
3. feat: Authentication Mode
      - **Proxifier Mode**: Support `-M proxifier` to enable proxifier mode, automatically intercepting specific requests for certificate verification.
4. feat: Tunnel Proxy Enhancement
      - **Confirmation Mechanism**: Tunnel proxy supports a confirmation mechanism, improving proxy stability.
      - **Connection Recovery**: Fixed an issue where HTTP requests going through tunnel proxy did not call `socket.resume()`.
      - **Line-Level Proxy Configuration**: Added `lineProps://proxyHost|proxyTunnel` to apply only to the current line.
5. feat: Multi-Layer Proxy Support
      - **Two-Layer Proxy**: Added `enable://proxyTunnel` to support two-layer HTTP proxy.
      - **Internal Request Support**: Internal path requests also support `enable://proxyTunnel`.
      - **Protocol Conversion Fix**: Fixed an issue where `https2http-proxy` could not properly convert some requests.
6. feat: WebSocket Handling
      - **Auto Conversion**: WebSocket HTTPS requests configured in hosts support automatic conversion to HTTP.
      - **Origin Fix**: Fixed an issue with automatic modification of WebSocket origin.
      - **Data Retention**: Retain tunnel proxy request header data after intercepting HTTPS requests.
7. feat: Plugin Management
      - **Status Display**: Plugins disabled show a `Disabled` indicator on the page tab.
      - **Command Customization**: Support customizing uninstall and install command names in the plugins list.
      - **Rule Data Retrieval**: Plugins can obtain rule matching results via `req.originalReq.ruleUrl`.
8. feat: Plugin Feature Enhancements
      - **Trailer Support**: Plugins automatically add trailers, which can be disabled via `res.disableTrailer`.
      - **Event Listening Optimization**: Optimized listening for `res.on('end', cb)` events to ensure triggering.
9. feat: Data Deletion and Clearing
      - **Content Deletion**: Support deleting request and response content via `delete://body`.
      - **Selective Deletion**: Support `delete://req.body` and `delete://res.body` for separate deletion.
      - **Content Clearing**: Support clearing request or response content via `reqBody://()` or `resBody://()`.
10. feat: Trailer Operations
      - **Trailer Passing**: Support passing `trailers`.
      - **Trailer Deletion**: Support deleting specified trailers via `delete://trailer.xxx|trailer.yyy`.
      - **Trailer Modification**: Support modification via `headerReplace://trailer.key:pattern=value` and `trailers://json`.
11. feat: Protocol Optimization
      - **SNI Control**: `enable://servername` removes SNI from HTTPS requests.
      - **StatusCode Adjustment**: `statusCode` moved into `rule` at the same level as `file` and other protocols.
      - **CORS Optimization**: `resCors://enable` automatically sets CORS fields for OPTIONS requests.
12. feat: Interface Layout
      - **Left Menu Control**: Support hiding the left menu via the `hideLeftMenu=true` request parameter.
      - **Rule Toggle**: Left menu adds checkboxes to quickly disable or enable Rules/Plugins.
      - **System Hosts**: Removed the option to sync system hosts.
13. feat: Data Display
      - **Time Precision**: Page time now supports displaying milliseconds.
      - **Encoding Display**: Fixed incorrect Content Encoding display on pages.
      - **Response Header Size**: Fixed header size display issues when h2 requests are converted to https requests in the UI.
14. feat: Shortcut Optimization
      - **General Replay**: Added shortcuts `ctrl[cmd] + r` or `ctrl[cmd] + shift + r` to replay requests.
      - **Frames Replay**: Frames support shortcut `Ctrl/Cmd + R` to replay requests.
15. feat: Interaction Enhancement
      - **Request Header Display**: Bold whistle custom request headers in Composer.
      - **Network Font**: Adjusted bold effect of Network font.
      - **Data Marking**: Network right-click menu added `Actions>Mark` to mark captured packet data.
16. feat: Command Line Tools
      - **Docker Deployment**: Support `w2 run -M prod` for convenient Docker deployment.
      - **Multi-Rule Mode**: Support enabling multi-select via `-M useMultipleRules`.
      - **Plugin Path**: Fixed an issue where `--addon "path1,path2"` could not accept multiple paths.
17. feat: Development Configuration
      - **JSON5 Configuration**: Support json5 configuration files.
      - **Node Requirement**: Node13~14 for HTTP2 functionality, minimum Node version requirement changed to 6.
      - **Template Variables**: Template strings support obtaining system `os.hostname()` via `${hostname}`.
18. feat: HTTP2 Support
      - **HTTP2 Compatibility**: Fixed an issue where HTTP2 could not be used with `Node >= 14.1`.
      - **Protocol Detection**: Automatic detection of whether request or response content supports gzip.
19. feat: Data Compression
      - **Gzip Optimization**: CGI returning captured packet data now uses gzip.
      - **Performance Hint**: Composer input text length now prevents browser freezes.
20. feat: Filter Rules
      - **Rule Fix**: Restored matching order, fixing rule overriding issues.
      - **Response Header Filtering**: Fixed an issue where `includeFilter://h:key=pattern` could not match response headers.
21. fix: Issue Fixes
      - **Proxy Request Headers**: Fixed disorder in proxy request headers `Host`.
      - **Rule Conflict**: Fixed an issue where `reqHeaders://cookie=xxx` and `reqCookies://test=123` could not take effect simultaneously.
      - **Path Handling**: Fixed issues with modifying request URL parameters via `urlParams` and `pathReplace`.
      - **Composer Construction**: Fixed an issue where Composer constructing requests without a body did not set `content-length: 0`.
22. fix: Interface Fixes
      - **Overview Display**: Fixed script errors in the Overview interface when requests contained matching plugin rules.
      - **Plugin Sorting**: Fixed sorting jumps that could occur with simultaneously installed plugins.
      - **Frames Display**: Binary data font bolded in Frames page.
23. feat: Feature Enhancement
      - **JSON Operations**: JSON Tree supports copying child node data; JSONView right-click menu added `Collapse Parent`.
      - **Data Copy**: Support copying request headers as JSON text.
      - **WebSocket Status**: Support displaying WebSocket close error codes.
24. feat: Search and Help
      - **Search History**: Network search box added history function.
      - **Rule Help**: Overview rule list hover allows clicking to view help documentation.
      - **Plugin Installation**: Plugins added `ReinstallAll` button to copy plugin installation commands.
25. feat: File Handling
      - **Composer File Upload**: Support uploading local files.
      - **Proxy Standards**: Fixed pending issues caused by some services not following HTTP standards.
26. feat: Interface Access
      - **Guest Mode**: Added interfaces accessible in guest mode.
      - **Interface Security**: Reduced exposure of interfaces without login state.

## v2.4

1. feat: Mutual TLS Authentication Support
      - **Client-Server Mutual Authentication**: Support custom client certificates for mutual TLS authentication.
      - **Safe Mode**: Added startup parameter `-M safe` to enable safe mode with strict server certificate verification.
      - **Certificate Management**: `HTTPS > View all custom certificates` highlights expired certificates and supports copying installation paths.
2. feat: Certificate and Host Configuration
      - **Local Host Configuration**: Fixed an issue where HTTPS requests might fail if the local hosts file lacked `127.0.0.1 localhost`.
      - **Express Framework Fix**: Fixed an issue with the `x-powered-by` response header added by default by Express.
3. feat: HTTP2 Optimization
      - **Node Version Requirement**: Due to numerous bugs in the HTTP/2 module of lower Node versions, unified adjustment requires Node v12.12.0 or above for HTTP/2 support.
      - **HTTP2 Session Error**: Fixed potential `ERR_HTTP2_SESSION_ERROR` on some websites.
      - **DELETE Request Optimization**: HTTP2 `DELETE` requests with content automatically downgrade to HTTP/1.1.
      - **HTTP/2 Compatibility**: HTTP/2 supports DELETE requests with body.
3. feat: Proxy Feature Extensions
      - **Internal HTTP Proxy**: Added `internal-http-proxy` protocol, similar to `internal-proxy` but uses tunnel proxy for WebSocket requests.
      - **SOCKS Proxy Stability**: Fixed a crash issue when enabling `--socksServer port` and request exceptions occur.
      - **HTTPS Downgrade**: Support automatic downgrade of HTTPS requests with content (like post) to HTTP requests.
4. feat: Protocol Processing Improvements
      - **pipe Protocol Fix**: Fixed issues where request exceptions in `pipe` were not caught and HTTP request pipe failure.
      - **Rule Parsing Enhancement**: Support parsing pipe rules from request headers.
5. feat: Network Customization
      - **Custom Columns**: Support custom column display in Network via `style` protocol configuration.
      - **Frames Page Enhancement**:
        - Added Overview Tab for viewing basic frame data information.
        - Binary data font bolded.
      - **Search Filtering**: Fixed duplicate data issues in Network search filtering.
6. feat: Data Display Optimization
      - **Composer Response Data**: Response data passed to Composer changed to base64 format.
      - **Saz File Support**: Support displaying non-text content in saz files.
      - **Overview Panel**: Display matching `includeFilter` in Overview.
      - **Time Display**: Support displaying time consumed by HTTPS auto-conversion to HTTP in Overview.
7. feat: Rule Matching Display
      - **Filter Rule Display**: Display matching `includeFilter` rules in the Overview panel.
8. feat: Filter Rule Optimization
      - **includeFilter Fix**: Fixed an issue where `includeFilter://b:pattern` failed.
      - **Matching Logic Adjustment**: Adjusted `includeFilter` and `excludeFilter` matching:
        - Must satisfy one of all `includeFilter`.
        - Must not match any `excludeFilter`.
        - i.e., `excludeFilter://p1 excludeFilter://p2 includeFilter://p3 includeFilter://p4` is equivalent to `!(p1 || p2) && (p3 || p4)`.
9. feat: Remote Rule Management
      - **Update Mechanism Optimization**: Optimized remote rule update mechanism to prevent misjudgment of pull failure leading to rule clearance.
      - **Rule Conflict Fix**: Fixed an issue where setting `reqBody://(xxxx) method://post` could not take effect simultaneously.
10. feat: Startup Parameter Enhancement
      - **Version Notification Control**: Support disabling version update notifications via `-M disableUpdateTips` (for third-party integrations).
      - **Installation Process Optimization**: Removed warning prompts during installation.
      - **Configuration Fix**: Fixed host configuration errors introduced in the previous version.
11. feat: Network Configuration
      - **IPv6 Optimization**: Optimized IPv6 configuration.
      - **Interface Streamlining**: Removed redundant interfaces.
12. fix: Issue Fixes
      - **Host Configuration**: Fixed HTTPS failures due to local hosts file configuration issues.
      - **Express Response Header**: Fixed the `x-powered-by` response header added by default by Express.
      - **HTTP2 Error**: Fixed potential `ERR_HTTP2_SESSION_ERROR` on some websites.
      - **Rule Matching**: Fixed `includeFilter://b:pattern` failure.
      - **Proxy Exception**: Fixed crashes when enabling `--socksServer` and request exceptions occur.
      - **Rule Conflict**: Fixed simultaneous effect issue with `reqBody://(xxxx) method://post`.

## v2.3

1. feat: Significant List Performance Improvement
      - **Virtual List Technology**: Introduced `react-virtualized` library, greatly improving Network list rendering performance.
      - **Default Data Volume**: Default support for displaying 1500 captured packet items simultaneously.
      - **Custom Quantity**: Adjustable via `Network > Filter > Max Rows Number`.
      - **Memory Management**: Limited zlib concurrency to reduce memory leak risk.
2. feat: Dependency Management and Build
      - **Lock Dependency Versions**: Added `package-lock.json` to ensure dependency consistency.
      - **Build Stability**: Improved project build and deployment stability.
3. feat: Request Header Security Control
      - **x-forwarded-for Fix**: Fixed `x-forwarded-for` chaos issues.
      - **Custom Forwarding Headers**: Support custom forwarding addresses via `forwardedFor://ip` or `reqHeaders://x-forwarded-for=ip`.
      - **Proxy Forwarding Logic**: Direct requests do not carry `x-forwarded-for` by default; proxy forwarding automatically adds non-local IPs.
4. feat: HTTPS and Certificate Processing
      - **Non-SNI Request Support**: Fixed issues where non-SNI HTTPS requests could not be unpacked.
      - **HTTP2 Compatibility**: Fixed overly strict format requirements for request/response in HTTP2 module.
5. feat: Content Injection Security
      - **Strict HTML Check**: `enable://strictHtml` ensures injection only when the first non-whitespace character is `<`.
      - **Safe HTML Check**: `enable://safeHtml` prevents accidental injection into non-standard interfaces (checks not starting with `{{`).
      - **Mis-injection Protection**: Unified script injection for domains prevents accidental injection into non-HTML response types.
6. feat: Plugin Development Experience
      - **Runtime Identifier**: `@url` requests automatically carry `x-whistle-runtime-id`, helping plugins identify request source.
      - **Plugin Status Query**: Added `options.isEnable()` method to get plugin enable status.
      - **Template Variable Support**: Plugin configuration files support placeholders:
        - `{{whistlePluginName}}` - Gets plugin short name (excluding `whistle.`).
        - `{{whistlePluginPackage.xx.yy.zzz}}` - Gets values from plugin `package.json`.
      - **Plugin Sorting**: Fixed sorting jumps that could occur with simultaneously installed plugins.
7. feat: WebSocket Handling
      - **Status Code Passing**: When WebSocket returns a non-101 status, it's passed to the browser.
      - **Proxy Client IP**: Fixed an issue where WebSocket using `internal-proxy` could not accurately carry clientIp.
8. Proxy and Connection Management
      - **Proxy Retry Fix**: Fixed duplicate path addition after setting proxy retry.
      - **Socket Error Handling**: Force-set empty errorHandler for all sockets to prevent uncaught exceptions.
      - **Compression Control**: Support disabling `gzip` for all requests via startup parameter `-M noGzip`.
9. Cache Policy Adjustment
      - **Cache Priority**: `cache://xxx` now has the highest priority.
      - **Response Header Retention**: Support forced retention of original request headers via `cache://reserve`.
      - **Injection and Cache Coordination**: Fixed conflicts between `log://xxx`/`weinre://xxx` injection and caching.
10. feat: Network Interface Optimization
      - **Column Width Adjustment**: Network `URL` column supports width modification.
      - **Layout Improvement**: Optimized interface layout and interaction.

## v2.2

1. feat: Global HTTP2 Switch
      - **Interface Control**: Support enabling/disabling HTTP2 requests via `Network -> HTTPS -> Enable HTTP/2`.
      - **Local Enablement**: Can enable HTTP2 for specific requests locally via `pattern enable://h2`.
      - **Mode Switching**: After deselecting HTTP2, both receiving and sending requests switch to non-HTTP2.
2. feat: HTTP2 Performance Optimization
      - **Session Caching**: Optimized H2 session caching strategy, improving connection reuse efficiency.
      - **Node.js Compatibility**: Fixed Node.js version compatibility issues (issue #27384).
      - **Timeout Setting Optimization**: Removed request timeout settings, improved connection management.
3. feat: Command Line Rule Configuration
      - **Remote Rule Loading**: Support loading rules from remote URLs via `w2 start -r "@https://xxx"`.
      - **Local Rule File**: Support loading rules from local files via `w2 start -r "@filepath"`.
      - **Direct Rule Setting**: Support direct rule setting via `w2 start -r "www.test.com/path/to reqHeaders://x-test=1"`.
      - **Combined Configuration**: Support JSON.stringify format for combining multiple rule sources.
4. feat: Rule Execution Optimization
      - **Response Phase Rules**: Some rules executed only in the response phase are matched after request response.
      - **Performance Improvement**: Optimized rule matching timing, improving execution efficiency.
5. feat: HAR File Support
      - **Encoding Detection**: Support automatic detection of whether `xxx.har` files use base64 encoding.
      - **Data Compatibility**: Improved HAR file import compatibility and accuracy.
6. feat: Internal Request Handling
      - **Retry Mechanism Fix**: Fixed potential infinite loops due to internal request retries.
      - **Connection Stability**: Improved internal request handling logic to avoid infinite retries.
8. feat: Overall Optimization
      - **Code Refactoring**: Optimized H2 session management logic.
      - **Configuration Simplification**: Removed unnecessary request timeout settings.

## v2.1
1. feat: JSON Object Handling
      - **Array and Nested Support**: Multi-line JSON objects now support setting array and multi-level nested values.
      - **Smart Conversion Rules**:
        - Previous version: `[1]: "test"` converted to `{ "[1]": "test" }`
        - Current version: `[1]: "test"` converted to `var arr = []; arr[1] = 'test';`
      - **Complex Structure Support**: Support for complex nested structures like `[a.b[3].c]: abc`.
      - **Escape Control**: Using double quotes `"[xxx.yyy[n]]"` avoids automatic escaping.
2. feat: Domain Matching Extension
      - **Flexible Matching Syntax**:
        - `.test.com` - Matches `x.test.com` and `test.com`
        - `*.test.com` - Matches `x.test.com`, not `test.com`
        - `**.test.com` - Matches `x.test.com` and all its descendant domains
        - `***.test.com` - Matches `test.com` and all its descendant domains
      - **Precise Control**: Support adding protocols and paths for more precise matching, e.g., `http://.test.com/path/to/*`
3. feat: Custom Method Support
      - **Method Extension**: Composer interface supports custom request methods.
      - **Flexible Construction**: Users can construct and send various types of requests more flexibly.
4. feat: HTTP2 Performance Optimization
      - **Session Reuse**: Reduced HTTP2 session count; each client can fully reuse HTTP2 sessions.
      - **Connection Efficiency**: Improved HTTP2 connection reuse efficiency, reducing resource usage.
5. feat: Plugin Development Experience
      - **Hint Optimization**: Fixed an issue where custom plugin hints with only one completion data wouldn't display.
      - **Environment Variable Support**: Support setting Node path for forked plugin processes via environment variable `env.WHISTLE_PLUGIN_EXEC_PATH` or startup parameter `-M buildIn`.
      - **Path Control**: Defaults to global Node; specific Node paths can be specified as needed.
6. feat: Overview Panel Enhancement
      - **Compression Information Display**: Overview panel supports displaying request size before and after gzip.
      - **Data Size Display**: Fixed an issue where empty request/response content wouldn't show size.
7. fix: URL Replacement Fix
      - **Path Handling**: Fixed incorrect path handling in URL replacement `url replacementUrl`.
      - **Replacement Accuracy**: Ensure URL replacement operations accurately handle path parameters.
8. perf: Performance Optimization
      - **HTTP2 Connection**: Optimized HTTP2 session management, reducing connection creation overhead.
      - **Data Display**: Improved data display logic for empty content.

## v2.0.0
1. feat: **Support for HTTP2 Functionality**
	> Please ensure the Node version is [the latest LTS (>= 10.16.0) or Stable (>= 12.12.0) version](https://nodejs.org/en/), otherwise anomalies may occur, such as: [#24037](https://github.com/nodejs/node/issues/24037), [#24470](https://github.com/nodejs/node/issues/24470)
2. feat: `**/path/to` If `path/to` contains `*`, e.g., `*/cgi-*`, it is equivalent to `^*/cgi-*`.

## v1.17
1. feat: Support establishing connections between browser and whistle via HTTP2 (**requires updating [Node](https://nodejs.org) to version `v10.16.0` or above**)
2. refactor: Adjusted connection caching strategy; no long caching for any connections to reduce memory usage.

## v1.16
1. feat: Support plugins obtaining plugin Rules, Values, and custom certificate information via `options.getRules(cb), options.getValues(cb), options.getCustomCertsInfo(cb)` respectively.
2. feat: HTTPS menu dialog added `View Custom Certs` button for managing custom certificates.
3. feat: Support enabling debugging mode via `w2 run --inspect` or `w2 run --inspectBrk`.
4. feat: Plugin list added `Sync` button to fetch plugin rules or values and set them in the UI Rules or Values.
5. feat: Support custom auto-completion list functionality via plugin package.json configuration, e.g., `"whistleConfig: { "hintUrl": "/cgi-xxx/xxx" }"`.
6. feat: Support data transfer between plugin server hooks via `req.sessionStorage.[get|set|remove]`.

## v1.15
1. feat: Support starting a SOCKS v5 service on a specified port via command line parameter `--socksPort 1080` (currently only supports regular TCP requests).
2. feat: Plugin server added `req.passThrough()`, `req.request(url/options, cb)`, `req.writeHead(code, message, headers)` methods for forwarding requests from plugins to specified services.
3. feat: Support a no-capture-page mode via command line parameter `-M rules`, where the UI won't show Network, cannot capture packets, and plugins cannot obtain captured packet data via `req.getSession(cb)`.
4. feat: Support setting request font color/style/background color via `style://color=!xxx&fontStyle=xxxxx&bgColor=red`.
5. feat: Support adjusting proxy configuration priority above host via `enable://proxyFirst` (default: host > proxy).
6. fix: Fixed various issues encountered during operation.

## v1.14
1. feat: Added new protocols [pipe](https://wproxy.org/docs/rules/pipe.html), [headerReplace](https://wproxy.org/docs/rules/headerReplace.html).
2. fix: Fixed `querystring.parse('+')` automatically converting to space ' ' or `%2B` issue.
3. refactor: Optimized startup parameter [--max-http-header-size=size](https://nodejs.org/dist/latest-v10/docs/api/cli.html#cli_max_http_header_size_size).
4. feat: Added command line parameters `--httpPort` and `--httpsPort` for starting regular HTTP and HTTPS servers respectively, useful for reverse proxying, and can also start another `http proxy` (same function as default HTTP proxy) and `https proxy` (can serve as an HTTPS proxy server).
5. fix: Fixed various issues encountered during operation.

## v1.13
1. feat: Enhanced plugin functionality, supporting `resRules.txt`.
2. feat: Added new protocols [excludeFilter](http://wproxy.org/docs/rules/excludeFilter.html) and [includeFilter](http://wproxy.org/docs/rules/includeFilter.html).
3. feat: [log](http://wproxy.org/docs/rules/log.html) supports injecting `whistle.onWhistleLogSend(level, logStr)` to obtain page log information for custom reporting.
4. feat: Plugins support custom interface URL via package.json configuration `"pluginHomepage": "http://xxx.xxx.com/"`.
5. feat: Local replacement added response `206` functionality, supporting iOS playback of locally replaced video files.
6. feat: Command line added `--no-prev-options` startup option, supporting `w2 restart` without reusing previous options.

## v1.12
1. feat: Support adjusting rule priority order in `Rules > Settings > The later rules first`. Default is top-to-bottom, with rules in Default having the lowest priority. This setting only applies to rules configured in Rules, not to [reqScript](https://wproxy.org/docs/rules/reqScript.html) or plugin-set rules.
2. feat: Added new protocol [https-proxy](https://wproxy.org/docs/rules/https-proxy.html).
3. feat: [resCookies](https://wproxy.org/docs/rules/resCookies.html) supports setting [SameSite](https://www.owasp.org/index.php/SameSite).
4. feat: Support loading remote rules via configuration `@url` or `@filepath` or `@whistle.xxx/path` in Rules.
5. feat: Support setting `shadowRules` via command line `-r, --shadowRules [shadowRules]`.
6. feat: Support embedded Values.
7. feat: Template strings support `replace`, and support submatching.
    ```
    pattern protocol://`${search.replace(pattern1,replacment)}`
    www.test.com file://`${search.replace(/Course_(id)\,?/ig,$1cid)}${test.html}`
    ```
    `pattern1` is a regex or regular string (no quotes needed).

## v1.11
1. feat: HTTPS request auto-downgrade ([https://github.com/avwo/whistle/issues/176](https://github.com/avwo/whistle/issues/176)).
2. feat: Support displaying HexView (binary).
3. feat: Added new protocol [xhost](https://wproxy.org/docs/rules/xhost.html).
4. feat: Adjusted strategy; some protocols support multiple simultaneous matches.
5. fix: Fixed various issues encountered during operation.

## v1.10
1. feat: Enhanced interface functionality.
2. feat: Support port matching `:12345 operation`.
3. feat: Support setting multiple domains for accessing webui `-l "webui1.example.com|webui2.example.com"`.
4. feat: Support obtaining rule configuration output by `.whistle.js` in the current directory via command line `w2 add`. See: [Command Line Parameters](https://wproxy.org/docs/cli.html).
5. feat: Display current whistle running status via `w2 status [-S storage]` or `w2 --all`.

## v1.9
1. feat: Support setting to capture-only mode via command line `-M network`. In this mode, only packet capture can be viewed; rules cannot be set nor plugins loaded.
2. feat: Support customizing domains for accessing plugins via command line `-L "script=a.b.com&vase=x.y.com&nohost=imweb.nohost.pro"`.
3. feat: Composer supports setting Rules.

## v1.8
1. feat: Added new protocols [htmlPrepend](https://wproxy.org/docs/rules/htmlPrepend.html), [htmlBody](https://wproxy.org/docs/rules/htmlBody.html), [htmlAppend](https://wproxy.org/docs/rules/htmlAppend.html), [cssPrepend](https://wproxy.org/docs/rules/cssPrepend.html), [cssBody](https://wproxy.org/docs/rules/cssBody.html), [cssAppend](https://wproxy.org/docs/rules/cssAppend.html), [jsPrepend](https://wproxy.org/docs/rules/jsPrepend.html), [jsBody](https://wproxy.org/docs/rules/jsBody.html), [jsAppend](https://wproxy.org/docs/rules/jsAppend.html).
2. feat: Support wildcard matching.
3. feat: Support `Copy As CURL`.
4. feat: Support importing HAR files.
5. feat: Support third-party extensions for the `@` symbol function in Rules.

## v1.7
1. feat: Added new protocols [resScript](https://wproxy.org/docs/rules/resScript.html), [responseFor](https://wproxy.org/docs/rules/responseFor.html), [resforwardedForScript](https://wproxy.org/docs/rules/forwardedFor.html).
2. fix: Fixed various issues encountered during operation.

## v1.6
1. feat: Support WebSocket request mapping, `ws://www.test.com/xxx https://www.abc.com/a/b`.
2. feat: Adjusted certificate strategy to prevent invalid characters in domains causing Chrome certificate validation failures.
3. fix: Fixed various issues encountered during operation.

## v1.5
1. feat: Composer supports constructing WebSocket and TCP requests.
2. feat: Support custom Whistle management interface port via command line parameter `-P uiPort`.
3. feat: Enhanced plugin functionality, supporting setting plugin-private Values via root directory file `_values.txt` (does not support `values.txt`), matching private rules `_rules.txt`.
4. feat: Interface supports left menu mode and displays client and server port numbers.
5. fix: Fixed various issues encountered during operation.

## v1.4
1. feat: Support modifying the root path of Whistle storage directory via command line parameters `-D, -baseDir`.
2. perf: Optimized performance of `os.networkInterfaces`.
3. fix: Fixed various issues encountered during operation.

## v1.3
1. feat: Pattern added support for schema-less mode `//xxx`.
2. fix: Fixed various issues encountered during operation.

## v1.2
1. feat: Added new protocols [reqScript](https://wproxy.org/docs/rules/reqScript.html), [ignore](https://wproxy.org/docs/rules/ignore.html), [enable](https://wproxy.org/docs/rules/enable.html).
2. feat: Enhanced plugin functionality, added `statsServer`.
3. feat: Added short link for downloading root certificate `http://rootca.pro`.

## v1.1
1. feat: Added new protocols [pac](https://wproxy.org/docs/rules/pac.html), [delete](https://wproxy.org/docs/rules/delete.html), [reqHeaders](https://wproxy.org/docs/rules/reqHeaders.html), [resHeaders](https://wproxy.org/docs/rules/resHeaders.html).
2. feat: Enhanced plugin functionality.
3. fix: Fixed various issues encountered during operation.

## v1.0
1. feat: Enhanced plugin functionality, added `tunnelServer`, support for new protocol `whistle.xxx://`.
2. feat: Enhanced `socks`, `proxy` protocol functionality.
3. feat: Added command line parameter `-l, --localUIHost` to modify the domain for accessing the configuration page, default is `local.whistlejs.com`.
4. feat: Proxy requests added `x-whistle-policy` for setting Whistle policies.
5. fix: Fixed various issues encountered during operation.
6. feat: Replaced with a new logo, thanks to our department's visual designer **[@wjdgh1031(鬼刀)](https://github.com/wjdgh1031)** for designing the new logo.
7. feat: Enhanced protocol functionality [pathReplace](https://wproxy.org/docs/rules/pathReplace.html), [log](https://wproxy.org/docs/rules/log.html), [replaceStatus](https://wproxy.org/docs/rules/replaceStatus.html), [rawfile](https://wproxy.org/docs/rules/rawfile.html), [xrawfile](https://wproxy.org/docs/rules/xrawfile.html), [reqAppend](https://wproxy.org/docs/rules/reqAppend.html), [resAppend](https://wproxy.org/docs/rules/resAppend.html), [reqType](https://wproxy.org/docs/rules/reqType.html), [resType](https://wproxy.org/docs/rules/resType.html), [reqCharset](https://wproxy.org/docs/rules/reqCharset.html), [ua](https://wproxy.org/docs/rules/ua.html), [reqWriter](https://wproxy.org/docs/rules/reqWriter.html), [reqWriterRaw](https://wproxy.org/docs/rules/reqWriterRaw.html), [reqReplace](https://wproxy.org/docs/rules/reqReplace.html), [resReplace](https://wproxy.org/docs/rules/resReplace.html), etc.
8. feat: Support exporting captured packet data.
9. feat: Support starting multiple instances `w2 start -S newStorageDir -p newPort`.
10. feat: Support custom plugins.
11. fix: Fixed various issues encountered during operation.


================================================
FILE: CHANGELOG.md
================================================
中文 · [English](./CHANGELOG-en_US.md)

## v2.10.1
1. fix: https://github.com/avwo/whistle/issues/1296
2. fix: https://github.com/avwo/whistle/issues/1297
2. feat: 支持快速筛选出匹配规则的请求

## v2.10.0
1. feat: Inspectors 的 Raw Tab 放到第一个位置
2. feat: 映射到本地的路径不允许包含 `../` 路径片段
3. feat: 允许禁用或开启自定义证书,无需删除
4. feat: 插件变量 `%plugin-name=xxx` 支持所有插件 hooks
5. refactor: 简化 Whistle 与插件间的代码传递方式,提升效率
6. fix: 完善测试用例,修复隐藏 bug

## v2.9
1. feat: 界面与体验优化:
      - 根据 Dark 模式规范重新优化界面 Dark 模式
      - Network 支持通过类型快速过滤、手动保存抓包数据
      - Composer 支持导入 CURL、显示 SSE/Websocket 内容
      - JSON Viewer 右键支持复制选中文本
      - 支持显示 TTFB、SSE 内容、WebSocket Frames
      - 新增 frameScript 用于通过 JS 修改 WebSocket/TCP 请求内容
2. feat: 规则与配置增强:
     - 支持通过 `~/.whistlerc` 加载默认配置
     - Rules 支持查看 `Enabled Rules`、分组功能
     - 支持设置匹配概率 `includeFilter://chance:0.5`
     - 新增 `delete://` 协议支持删除请求参数、cookie等
     - 支持 `req.passThrough({transformReq, transformRes, ...})`
     - 内嵌值添加作用域(Rules、插件、Header Rules 相互独立)
3. feat: 插件系统改进:
     - 支持通过界面安装/卸载插件
     - 插件列表添加自定义右键菜单
     - 插件支持 `sharedStorage` 在不同实例中共享数据
     - 插件 Option 页面支持设置 favicon、以对话框形式打开
     - 支持通过插件安装插件
4. feat: 网络与代理功能:
     - 默认启用 `localhostCompatible` 模式
     - 支持 IPv6-only 网络
     - 支持 socks 代理、自定义 DNS server
     - 新增 `https-proxy`、`internal-http-proxy` 协议
     - 支持 HTTP2 功能(需 Node 10.16.0+)
5. feat: 证书与安全:
     - 证书默认格式改为 cer 适配更多机型
     - 支持自定义客户端证书和双向认证
     - 根证书过期后可通过 `w2 ca` 更新

## v2.8
1. feat: 多进程支持
      - 新增 `--cluster [workers]` 启动模式,支持多进程运行
      - 修复启动时绑定非本地网卡时插件远程规则访问失败问题
2. feat: 证书管理优化
      - 自动生成的证书过期时自动续期(有效期一年)
      - 禁止通过页面上传根证书文件(`root.key & root.crt`)
      - 支持非 SNI 请求通过插件自定义证书
      - 支持直接上传和删除用户自定义证书
3. feat: 插件系统增强
      - 插件 `server` 钩子支持通过 `req.setReqRules` 和 `req.setResRules` 设置动态规则
      - 插件可获取客户端连接信息(`originalReq.remoteAddress` 与 `originalReq.remotePort`)
      - 修复插件 `sniCallback` 返回 `false` 时请求未重新走 TUNNEL 代理的问题
      - 优化插件规则执行:req 和 res rules 分开执行
4. feat: 代理规则增强
      - 支持通过 `ignore://-*` 过滤 `ignore://*`
      - 支持 `proxy` 和 `pac` 配置 `lineProps://proxyHostOnly`,仅当用户配置了 `host` 时代理生效
      - `--httpsPort` 启动的 HTTPS Server 支持从插件获取证书
5. feat: 过滤规则扩展
      - 支持通过 `excludeFilter://from=httpServer`、`includeFilter://from=httpsServer` 等按来源过滤请求
      - 支持通过 `enable://useLocalHost` 和 `enable://useSafePort` 修改 log 和 weinre 请求的域名或端口
6. feat: 请求头控制
      - 默认不启用 `x-forwarded-host` 和 `x-forwarded-proto`,可通过以下方式启用:
      - 启动参数 `-M x-forwarded-host|x-forwarded-proto`
      - 请求头 `x-whistle-forwarded-props: host,proto,for,clientIp,ip`
7. feat: 自定义界面
      - 支持自定义 `inspectors tab`
      - 界面提供 `api.selectIndex` 方法选中指定下标的抓包数据
8. feat: 数据限制与优化
      - 默认显示的抓包数据不超过 1.5MB,可通过 `enable://bigData` 扩大到 2.5MB
      - 支持通过请求头设置响应规则
      - 优化获取证书逻辑,合并多次相同请求
9. 文件路径处理
      - `reqWrite:///path/to/` 和 `reqWrite:///path/to` 区别处理,前者自动补全为 `index.html`
10. 合并操作增强
      - `resMerge://json1 resMerge://json2` 默认使用浅合并,可通过 `resMerge://true` 启用深合并
11. feat: 强制写入支持
      - 支持通过 `enable://forceReqWrite` 和 `enable://forceResWrite` 强制 `reqWrite`、`reqWriteRaw` 和 `resWrite`、`resWriteRaw`
12. feat: 认证钩子优化
     - 插件的 auth hook 默认对解析后的 HTTPS 请求生效
     - 支持通过 `enable://authCapture` 使 auth hook 对隧道代理请求生效
13. fix: 问题修复
     - 修复可能无法导入 saz 文件的问题
     - 修复 `sniCallback` 内存泄露问题
     - 处理 `unhandledRejection` 事件
14. refactor: 代码优化
     - 插件接收到 HTTPS 请求时,`req.url` 将包含完整路径
     - 优化获取证书逻辑,减少重复请求
     - 支持通过 `disable://abort` 禁用 `enable://abort`

## v2.7

1. feat: HTTP2 功能扩展
      - **HTTP2 非 HTTPS 支持**:HTTP2 协议现在支持非 HTTPS 请求
      - **性能监控**:第三方集成可通过 `proxy.on('perfDataChange')` 获取 CPU、内存、请求量等运行数据
2. feat: 插件系统全面增强
      - **异步支持**:插件 hook 现在支持 `async-await` 语法
      - **认证集成**:插件 `whistleConfig` 支持配置 `inheritAuth` 复用 Whistle 登录账号
      - **插件管理**:支持在插件根目录执行 `w2 run` 时自动加载该插件
      - **配置共享**:插件支持通过 `options.getCert()` 获取指定域名证书
      - **依赖引用**:插件可通过 `options.require` 直接引用 Whistle 内部模块
3. feat: 命令行工具改进
      - **配置管理**:支持通过 `--config localFile` 加载启动配置(优先级高于命令行)
      - **实例管理**:优化 `w2 stop` 命令,找不到实例时显示所有运行实例
      - **Docker 支持**:源码目录添加 Dockerfile
4. feat: DNS 解析增强
      - **自定义 DNS**:支持通过 `--dnsServer` 参数自定义 DNS 服务器
      - **DNS over HTTPS**:支持类似 `http://dns.alidns.com/resolve` 的 DNS-over-HTTPS 服务
      - **IPv6 支持**:可手动指定 IPv6 DNS 服务器地址
5. feat: 代理协议优化
      - **PAC 认证**:`pac` 协议支持设置用户名密码:`pac://user:pass@pacPath`
      - **隧道代理**:支持插件设置 `tunnelKey` 传递隧道代理请求头
      - **代理转发**:优化 `lineProps://proxyHost|proxyTunnel|proxyFirst` 配置
6. feat: 请求头处理
      - **转发控制**:支持通过 `-M disableForwardedHost` 和 `-M disableForwardedProto` 禁用特定转发头
      - **自定义解析**:`pipe://xxx` 支持插件内部获取原始规则值
7. feat: Network 视图升级
      - **Tree View 支持**:Network 支持树形视图展示抓包数据
      - **原始 URL 显示**:支持显示原始 URL(Raw Url)
      - **数据量显示**:Network 的 Body 列显示请求内容大小
      - **列表优化**:修复 Tree View 和 List View 的数据更新和排序问题
8. feat: 界面交互改进
      - **Composer 历史**:优化 Composer 历史记录列表显示
      - **左侧菜单**:优化左侧菜单布局和交互
      - **状态提示**:禁用 Rules 和 Plugins 时显示更明显的提醒
      - **快捷键支持**:Values 右键菜单修复快捷键问题
9. feat: 规则编辑器增强
      - **规则排序**:支持将 Rules 添加到最前面
      - **错误处理**:修复 Rules 编辑器输入 `!` 时报错的问题
      - **智能提示**:`pipe` 协议支持智能提示功能
10. feat: 认证功能扩展
        - **插件认证**:插件 `auth` 方法支持 `req.setRedirect(url)` 重定向
        - **登录框支持**:插件 `auth` 支持设置 `req.showLoginBox` 弹出登录框
        - **内部请求**:插件 `auth` 方法现在支持处理 Whistle 内部请求
11. feat: 证书管理
        - **根证书管理**:支持显示自定义根证书及删除导引
        - **远程证书**:支持通过插件 `sniCallback(req, options)` hook 获取远程证书
12. feat: 自定义解析器
        - **HTTP 解析**:普通 HTTP 请求现在也支持 `customParser`(或 `customFrames`)
        - **数据替换**:修复 `reqReplace` 及 `resReplace` 因拆包导致的匹配不准确问题
13. feat: 协议支持扩展
        - **状态码替换**:WebSocket 和 Tunnel 请求支持 `replaceStatus`
        - **控制台日志**:支持通过 `disable://interceptConsole` 禁止 `log://` 拦截 `console`
        - **CORS 处理**:`resCors://enable` 在请求头不存在 `origin` 时自动忽略
14. feat: 内存优化
        - **空请求处理**:去掉 `Empty Request` 减少内存和 CPU 占用
        - **栈溢出修复**:修复 Maximum call stack size exceeded 错误
        - **存储分离**:插件在不同实例使用不同的存储目录
15. feat: 启动与运行优化
        - **启动速度**:优化 Whistle 启动速度
        - **延迟实现**:优化 `reqDelay` 和 `resDelay` 的实现机制
        - **插件加载**:第三方集成可监听插件加载事件
16. feat: 模板字符串增强
        - **端口变量**:支持在模板字符串中通过 `clientPort` 和 `serverPort` 获取端口信息
        - **插件变量**:支持在规则中同时设置多个 `%plugin-name=xxxx`(最多10个)
17. fix: 问题修复
        - **对话框定制**:`alert`、`confirm`、`prompt` 等浏览器内置窗口改用自定义实现,防止 Chrome 限制
        - **WebSocket 抓包**:修复 WebSocket 无法抓包的问题
        - **插件存储**:修复插件使用 `storage.setProperties` 失效问题
        - **请求暂停**:修复某些情况下响应 stream pause 问题
        - **第三方集成**:修复第三方集成时的内部请求转发问题
18. feat: 功能调整
        - **删除时机**:调整 `delete://reqH.xxxx` 的执行时机
        - **转发逻辑**:优化内部请求转发逻辑的实现方式
19. feat: 其他改进
        - **规则模式**:支持设置 `-M shadowRules`(抓包+设置规则)或 `-M shadowRulesOnly`(仅规则)
        - **UI 请求**:显示 UI 请求情况
        - **错误提示**:优化错误提示信息
        - **协议显示**:显示插件转发的 HTTP 协议类型

## v2.6

1. feat: 系统监控与状态
      - **在线状态监控**:通过 `Online` 菜单查看当前进程的请求数、CPU、内存状态
      - **API 监控接口**:支持通过 `proxy.getRuntimeInfo()` 获取运行时信息
      - **性能指标**:Online 面板支持显示 QPS 及内存、CPU、QPS 的最大值
2. feat: 数据管理
      - **回收站功能**:删除的 Rules 或 Values 先存放到回收站(最多缓存120条),支持恢复
      - **证书生成工具**:`Network > Tools > ToolBox` 支持通过域名生成对应证书
      - **HAR 文件导出**:支持导出抓包数据为 HAR 格式文件
3. feat: Network 功能增强
      - **高级搜索**:搜索框支持最多3个关键字过滤
      - **源码查看**:右键菜单新增 `Open/Source` 查看抓包数据源码
      - **SVG 预览**:支持预览 SVG 文件
4. feat: 编辑器与规则管理
      - **只读模式**:支持通过 `disabledEditor=1` 参数将 Rules & Values 编辑器设置为只读模式
      - **行号注释**:启用行号显示时,双击行数可注释或取消注释
      - **规则高亮**:优化编辑器对插件规则的高亮显示
5. feat: 交互改进
      - **工具集扩展**:`Network / Tools / Toolbox` 支持将对象转成 Query 参数
      - **快捷操作**:支持扩展 `util.openEditor(value)` 方法
6. feat: 规则导入导出
      - **规则导入**:支持通过 `--shadowRules jsonString` 导入规则到 Rules
      - **命令行输出**:优化命令行启动时的信息显示
7. feat: 模式设置
      - **运行模式**:支持 `-M` 参数设置多种模式:
      - `disabledBackOption|disabledMultipleOption|notAllowDisableRules`
      - `rulesOnly` 及 `pluginsOnly`
8. feat: 内部路径处理
      - **路径灵活性**:内部路径支持设置域名和端口参数,格式:
      - `/...whistle-path.5b6af7b9884e1165...///__domain__port__/path/to`
      - `/...whistle-path.5b6af7b9884e1165...///path/to?_whistleInternalHost_=__domain__port__`
9. 内存与连接管理
      - **连接优化**:确保及时关闭无用连接,减少内存占用
      - **GC 优化**:调整 GC 参数 `--max-semi-space-size=64`
      - **性能监控**:支持通过 CGI 或 API 获取当前处理的请求总数
10. feat: 异常处理
        - **插件异常**:支持通过 `process.on('pforkError')` 获取插件抛出的异常信息
        - **未捕获异常**:优化处理请求过程中无法捕获的异常
        - **超时处理**:`onSocketEnd` 添加 `timeout` 事件,兼容各种异常情况
11. feat: 内部连接
        - **连接管理**:优化内部连接管理机制
12. feat: 过滤规则
        - **规则修复**:修复 `excludeFilter` 和 `includeFilter` 混合配置时结果错乱问题
        - **域名匹配**:域名通配符现在支持获取子匹配内容
13. feat: 代理配置
        - **代理连接头**:支持通过 `disable://proxyConnection` 将代理转发头改为 `Proxy-Connection: close`
        - **客户端过滤**:支持通过 URL 参数的 clientId 过滤抓包数据
14. fix: 主要问题修复
        - **规则文件保存**:修复规则文件名称过长时保存失败的问题
        - **编辑器问题**:修复编辑器高亮显示插件规则的问题
        - **管理界面安全**:修复管理界面 CGI 路径可以随意拼接的问题
        - **Node 版本兼容**:修复特定 Node 版本(v15.5.0)的兼容性问题
        - **pipe 协议**:修复可能导致数据丢失的问题
        - **本地文件替换**:本地文件替换的响应头默认加入 `content-length` 字段
15. perf: 性能问题
        - **卡死问题**:修复部分 Node 版本可能卡死的问题
        - **连接泄漏**:优化连接管理,减少资源占用
16. feat: 响应头处理
        - **内容长度控制**:本地文件替换时自动添加 `content-length` 字段,可通过 `delete://resH.content-length` 禁用
17. 内部请求处理
        - **异步处理**:支持通过 `process.on('pforkError')` 监听插件进程异常

## v2.5

1. feat: 客户端证书支持
      - **自定义客户端证书**:支持配置自定义客户端证书,增强安全认证能力
      - **连接错误处理**:优化建立连接时的错误处理机制
2. feat: 安全协议增强
      - **加密算法扩展**:添加 `cipher` 协议支持自定义兜底加密算法
      - **安全更新**:更新 node-forge 解决已知安全问题
      - **插件安全控制**:启动参数支持通过 `allowPluginList` 和 `blockPluginList` 控制插件加载
3. feat: 认证模式
      - **Proxifier 模式**:支持 `-M proxifier` 开启 proxifier 模式,自动拦截特定请求进行证书判断
4. feat: 隧道代理增强
      - **确认机制**:tunnel 代理支持确认机制,提升代理稳定性
      - **连接恢复**:修复 HTTP 请求走 tunnel 代理未调用 `socket.resume()` 的问题
      - **行级代理配置**:新增 `lineProps://proxyHost|proxyTunnel` 只对当前行生效
5. feat: 多层代理支持
      - **双层代理**:添加 `enable://proxyTunnel` 支持两层 HTTP 代理
      - **内部请求支持**:内部路径请求也支持 `enable://proxyTunnel`
      - **协议转换修复**:解决 `https2http-proxy` 部分请求无法正常转换问题
6. feat: WebSocket 处理
      - **自动转换**:配置 hosts 的 WebSocket HTTPS 请求支持自动转 HTTP
      - **Origin 修复**:修复自动修改 WebSocket origin 问题
      - **数据保留**:拦截 HTTPS 请求后保留 tunnel 代理请求头数据
7. feat: 插件管理
      - **状态显示**:插件禁用后在页面标签显示 `Disabled` 标识
      - **命令自定义**:支持自定义 plugins 列表的卸载及安装命令名称
      - **规则数据获取**:插件可通过 `req.originalReq.ruleUrl` 获取规则匹配结果
8. feat: 插件功能增强
      - **Trailer 支持**:插件自动添加 trailers,可通过 `res.disableTrailer` 禁用
      - **事件监听优化**:优化监听 `res.on('end', cb)` 事件,确保事件触发
9. feat: 数据删除与清空
      - **内容删除**:支持通过 `delete://body` 删除请求及响应内容
      - **选择性删除**:支持 `delete://req.body` 和 `delete://res.body` 分别删除
      - **内容清空**:支持通过 `reqBody://()` 或 `resBody://()` 清空请求或响应内容
10. feat: Trailer 操作
      - **Trailer 传递**:支持传递 `trailers`
      - **Trailer 删除**:支持通过 `delete://trailer.xxx|trailer.yyy` 删除指定 trailer
      - **Trailer 修改**:支持通过 `headerReplace://trailer.key:pattern=value` 及 `trailers://json` 修改
11. feat: 协议优化
      - **SNI 控制**:`enable://servername` 删除 HTTPS 请求的 SNI
      - **状态码调整**:`statusCode` 移入 `rule` 里面跟 `file` 等协议同级
      - **CORS 优化**:`resCors://enable` 自动设置 OPTIONS 请求的跨域字段
12. feat: 界面布局
      - **左侧菜单控制**:支持通过请求参数 `hideLeftMenu=true` 隐藏左菜单
      - **规则开关**:左侧菜单新增 checkbox 快速禁用或启用 Rules/Plugins
      - **系统 hosts**:去掉同步系统 hosts 设置
13. feat: 数据显示
      - **时间精度**:页面时间支持显示毫秒
      - **编码显示**:修复页面 Content Encoding 显示错误问题
      - **响应头大小**:修复 h2 请求转成 https 请求时界面显示响应头大小问题
14. feat: 快捷键优化
      - **通用重放**:添加快捷键 `ctrl[cmd] + r` 或 `ctrl[cmd] + shift + r` 重放请求
      - **Frames 重放**:Frames 支持快捷键 `Ctrl/Cmd + R` 重放请求
15. feat: 交互增强
      - **请求头显示**:加粗 Composer 里面的 whistle 自定义请求头
      - **Network 字体**:调整 Network 字体加粗效果
      - **数据标记**:Network 右键菜单添加 `Actions>Mark` 标记抓包数据
16. feat: 命令行工具
      - **Docker 部署**:支持 `w2 run -M prod` 方便 Docker 部署
      - **多规则模式**:支持通过 `-M useMultipleRules` 启用多选
      - **插件路径**:修复 `--addon "path1,path2"` 无法填多个路径问题
17. feat: 开发配置
      - **JSON5 配置**:支持 json5 配置文件
      - **节点要求**:Node13~14 开启 http2 功能,Node 版本最低要求改为 6
      - **模板变量**:模板字符串支持通过 `${hostname}` 获取系统的 `os.hostname()`
18. feat: HTTP2 支持
      - **HTTP2 兼容性**:修复 `Node >= 14.1` 无法使用 http2 问题
      - **协议检测**:自动检测请求或响应内容是否支持 gzip
19. feat: 数据压缩
      - **Gzip 优化**:gzip 返回抓包数据的 CGI
      - **性能提示**:Composer 输入的文本长度现在防止浏览器卡死
20. feat: 过滤规则
      - **规则修复**:还原匹配顺序,修复规则覆盖问题
      - **响应头过滤**:修复 `includeFilter://h:key=pattern` 无法匹配响应头问题
21. fix: 问题修复
      - **代理请求头**:修复代理请求头 `Host` 错乱问题
      - **规则冲突**:修复 `reqHeaders://cookie=xxx` 和 `reqCookies://test=123` 无法同时生效问题
      - **路径处理**:修复通过 `urlParams` 和 `pathReplace` 修改请求 URL 参数的问题
      - **Composer 构造**:修复 Composer 构造没有 body 的请求不设置 `content-length: 0` 问题
22. fix: 界面修复
      - **Overview 显示**:修复请求包含匹配的插件规则时 Overview 界面脚本报错问题
      - **插件排序**:修复同时安装的插件可能出现排序跳动问题
      - **Frames 显示**:Frames 页面二进制数据字体加粗
23. feat: 功能增强
      - **JSON 操作**:JSON Tree 支持复制子节点数据,JSONView 右键菜单新增 `Collapse Parent`
      - **数据拷贝**:支持将请求头以 JSON 文本拷贝
      - **WebSocket 状态**:支持显示 WebSocket 关闭的错误码
24. feat: 搜索与帮助
      - **搜索历史**:Network 搜索框添加历史记录功能
      - **规则帮助**:Overview 规则列表 hover 可点击查看帮助文档
      - **插件安装**:Plugins 添加 `ReinstallAll` 按钮,可复制插件安装命令
25. feat: 文件处理
      - **Composer 文件上传**:支持上传本地文件
      - **代理标准**:修复某些服务未按 HTTP 标准执行导致的 pending 问题
26. feat: 接口访问
      - **访客模式**:新增访客模式可以访问的接口
      - **接口安全**:减少暴露无登录态的接口

## v2.4

1. feat: 双向认证支持
      - **客户端服务端双向认证**:支持自定义客户端证书,实现客户端与服务端双向认证
      - **安全模式**:新增启动参数 `-M safe` 开启安全模式,严格校验服务端证书
      - **证书管理**:`HTTPS > View all custom certificates` 支持高亮显示过期证书,并支持复制证书安装路径
2. feat: 证书与主机配置
      - **本地主机配置**:修复本地 hosts 文件未配置 `127.0.0.1 localhost` 可能导致 HTTPS 请求失败问题
      - **Express 框架修复**:修复 Express 框架默认添加的 `x-powered-by` 响应头问题
3. feat: HTTP2 优化
      - **Node 版本要求**:鉴于低版本 Node 的 HTTP/2 模块 bug 较多,统一调整为 Node v12.12.0 及以上版本才支持 HTTP/2
      - **HTTP2 会话错误**:修复部分网站可能出现的 `ERR_HTTP2_SESSION_ERROR`
      - **DELETE 请求优化**:HTTP2 的 `DELETE` 请求如果携带请求内容,则自动降级为 HTTP/1.1
      - **HTTP/2 兼容性**:HTTP/2 支持 delete 请求携带 body
3. feat: 代理功能扩展
      - **内部 HTTP 代理**:新增 `internal-http-proxy` 协议,功能与 `internal-proxy` 类似,但对 WebSocket 请求使用 tunnel 代理
      - **SOCKS 代理稳定性**:修复启用 `--socksServer port` 后请求异常可能导致程序 crash 问题
      - **HTTPS 降级**:支持 post 等包含请求内容的 HTTPS 请求自动降级到 HTTP 请求
4. feat: 协议处理改进
      - **pipe 协议修复**:修复使用 `pipe` 时请求异常导致没有捕获问题,以及 HTTP 请求 pipe 失效问题
      - **规则解析增强**:支持从请求 headers 里面的规则解析出 pipe 规则
5. feat: Network 自定义化
      - **自定义列**:支持在 Network 中自定义列显示,通过 `style` 协议配置
      - **Frames 页面增强**:
        - 新增 Overview Tab 用于查看帧数据的基本信息
        - 二进制数据字体加粗显示
      - **搜索过滤**:修复 Network 搜索过滤可能出现重复数据的问题
6. feat: 数据展示优化
      - **Composer 响应数据**:传给 Composer 的响应数据改成 base64 格式
      - **Saz 文件支持**:支持显示 saz 文件里面的非文本内容
      - **Overview 面板**:在 Overview 里面显示匹配的 `includeFilter`
      - **时间显示**:支持在 Overview 里显示 HTTPS 自动转 HTTP 所消耗的时间
7. feat: 规则匹配显示
      - **过滤规则显示**:在 Overview 面板中显示匹配的 `includeFilter` 规则
8. feat: 过滤规则优化
      - **includeFilter 修复**:修复 `includeFilter://b:pattern` 失效问题
      - **匹配逻辑调整**:调整 `includeFilter` 和 `excludeFilter` 匹配方式
        - 需要满足所有 `includeFilter` 中的一个
        - 不能匹配到任何 `excludeFilter`
        - 即 `excludeFilter://p1 excludeFilter://p2 includeFilter://p3 includeFilter://p4` 相当于 `!(p1 || p2) && (p3 || p4)`
9. feat: 远程规则管理
      - **更新机制优化**:优化远程规则更新机制,防止误判拉取失败导致远程规则被清空
      - **规则冲突修复**:修复设置 `reqBody://(xxxx) method://post` 无法同时生效问题
10. feat: 启动参数增强
      - **版本通知控制**:支持通过 `-M disableUpdateTips` 禁用版本升级通知(适用于第三方应用集成)
      - **安装过程优化**:去掉安装过程中的 warning 提示
      - **配置修复**:修复上一个版本引入的配置 host 出错问题
11. feat: 网络配置
      - **IPv6 优化**:优化 IPv6 配置
      - **接口精简**:去掉多余的接口
12. fix: 问题修复
      - **主机配置**:修复本地 hosts 文件配置问题导致的 HTTPS 失败
      - **Express 响应头**:修复 Express 框架默认添加的 `x-powered-by` 响应头问题
      - **HTTP2 错误**:修复部分网站可能出现的 `ERR_HTTP2_SESSION_ERROR`
      - **规则匹配**:修复 `includeFilter://b:pattern` 失效问题
      - **代理异常**:修复启用 `--socksServer` 后请求异常导致程序 crash 问题
      - **规则冲突**:修复设置 `reqBody://(xxxx) method://post` 无法同时生效问题

## v2.3

1. feat: 列表性能显著提升
      - **虚拟列表技术**:引入 `react-virtualized` 库,极大提升 Network 列表渲染性能
      - **默认数据量**:默认支持同时显示 1500 条抓包数据
      - **自定义数量**:可通过 `Network > Filter > Max Rows Number` 调整显示数量
      - **内存管理**:限制 zlib 的并发量,减少内存泄露风险
2. feat: 依赖管理与构建
      - **锁定依赖版本**:添加 `package-lock.json` 确保依赖一致性
      - **构建稳定性**:提升项目构建和部署的稳定性
3. feat: 请求头安全控制
      - **x-forwarded-for 修复**:修复 `x-forwarded-for` 混乱问题
      - **自定义转发头**:支持通过 `forwardedFor://ip` 或 `reqHeaders://x-forwarded-for=ip` 自定义转发地址
      - **代理转发逻辑**:直接请求默认不带 `x-forwarded-for`,代理转发自动带上非本地 IP
4. feat: HTTPS 与证书处理
      - **非 SNI 请求支持**:修复非 SNI 的 HTTPS 请求无法解包问题
      - **HTTP2 兼容性**:修复 HTTP2 模块对请求响应格式要求过于严格的问题
5. feat: 内容注入安全
      - **严格 HTML 检查**:`enable://strictHtml` 确保仅当第一个非空白字符是 `<` 时才注入内容
      - **安全 HTML 检查**:`enable://safeHtml` 防止误注入到非标准接口(检查非 `{{` 开头)
      - **误注入防护**:统一给域名注入脚本时,防止非 HTML 响应类型被误注入
6. feat: 插件开发体验
      - **运行时标识**:`@url` 请求自动带上 `x-whistle-runtime-id`,便于插件判断请求来源
      - **插件状态查询**:新增 `options.isEnable()` 方法获取插件启用状态
      - **模板变量支持**:插件配置文件支持占位符:
        - `{{whistlePluginName}}` - 获取插件短名称(不包含 `whistle.`)
        - `{{whistlePluginPackage.xx.yy.zzz}}` - 获取插件 `package.json` 的值
      - **插件排序**:修复同时安装的插件可能出现的排序跳动问题
7. feat: WebSocket 处理
      - **状态码透传**:WebSocket 返回非 101 状态时,透传给浏览器
      - **代理客户端 IP**:修复 WebSocket 使用 `internal-proxy` 时无法准确带上 clientIp 的问题
8. 代理与连接管理
      - **代理重试修复**:修复设置代理重试后重复添加路径问题
      - **Socket 错误处理**:强制为所有 socket 设置空的 errorHandler,防止未捕获异常
      - **压缩控制**:支持通过启动参数 `-M noGzip` 禁用所有请求的 `gzip` 功能
9. 缓存策略调整
      - **缓存优先级**:`cache://xxx` 现在拥有最高优先级
      - **响应头保留**:支持通过 `cache://reserve` 强制保留原始请求头
      - **注入与缓存协调**:修复 `log://xxx` 和 `weinre://xxx` 注入时与缓存的冲突问题
10. feat: Network 界面优化
      - **列宽调整**:Network 的 `URL` 列支持修改宽度
      - **布局改进**:优化界面布局和交互体验

## v2.2

1. feat: 全局 HTTP2 开关
      - **界面控制**:支持通过 `Network -> HTTPS -> Enable HTTP/2` 关闭或开启 HTTP2 请求
      - **局部启用**:可以通过 `pattern enable://h2` 为特定请求局部开启 HTTP2
      - **模式切换**:取消选择 HTTP2 后,接收和发送请求的方式都改用非 HTTP2
2. feat: HTTP2 性能优化
      - **Session 缓存**:优化 H2 session 缓存策略,提升连接复用效率
      - **Node.js 兼容性**:修复 Node.js 版本兼容性问题(issue #27384)
      - **超时设置优化**:去掉请求超时设置,改进连接管理
3. feat: 命令行规则配置
      - **远程规则加载**:支持通过 `w2 start -r "@https://xxx"` 从远程 URL 加载规则
      - **本地规则文件**:支持通过 `w2 start -r "@filepath"` 从本地文件加载规则
      - **直接规则设置**:支持通过 `w2 start -r "www.test.com/path/to reqHeaders://x-test=1"` 直接设置规则
      - **组合配置**:支持 JSON.stringify 格式组合多个规则源
4. feat: 规则执行优化
      - **响应阶段规则**:部分在响应阶段才会执行的规则放到请求响应后再做匹配
      - **性能改进**:优化规则匹配时机,提高执行效率
5. feat: HAR 文件支持
      - **编码检测**:支持自动检测 `xxx.har` 文件是否使用 base64 编码
      - **数据兼容性**:改进 HAR 文件导入的兼容性和准确性
6. feat: 内部请求处理
      - **重试机制修复**:修复内部请求重试可能导致死循环的问题
      - **连接稳定性**:改进内部请求处理逻辑,避免无限重试
8. feat: 整体优化
      - **代码重构**:优化 H2 session 管理逻辑
      - **配置简化**:去掉不必要的请求超时设置

## v2.1
1. feat: JSON 对象处理
      - **数组与嵌套支持**:多行形式的 JSON 对象现在支持设置数组及多层嵌套的值
      - **智能转换规则**:
        - 以前版本:`[1]: "test"` 转换为 `{ "[1]": "test" }`
        - 现在版本:`[1]: "test"` 转换为 `var arr = []; arr[1] = 'test';`
      - **复杂结构支持**:支持类似 `[a.b[3].c]: abc` 的复杂嵌套结构
      - **转义控制**:使用双引号 `"[xxx.yyy[n]]"` 可以避免自动转义
2. feat: 域名匹配扩展
      - **灵活匹配语法**:
        - `.test.com` - 匹配 `x.test.com` 与 `test.com`
        - `*.test.com` - 匹配 `x.test.com`,不匹配 `test.com`
        - `**.test.com` - 匹配 `x.test.com` 及其所有子孙代域名
        - `***.test.com` - 匹配 `test.com` 及其所有子孙代域名
      - **精确控制**:支持添加协议及路径进行更精确匹配,如 `http://.test.com/path/to/*`
3. feat: 自定义方法支持
      - **方法扩展**:Composer 界面支持自定义请求方法
      - **灵活构造**:用户可以更灵活地构造和发送各种类型的请求
4. feat: HTTP2 性能优化
      - **Session 复用**:减少 HTTP2 的 session 数,每个客户端到 HTTP2 session 可以完全复用
      - **连接效率**:提升 HTTP2 连接的复用效率,减少资源占用
5. feat: 插件开发体验
      - **提示优化**:修复自定义插件 hint 只有一个补全数据不显示的问题
      - **环境变量支持**:支持通过环境变量 `env.WHISTLE_PLUGIN_EXEC_PATH` 或启动参数 `-M buildIn` 设置 fork 插件进程的 Node 路径
      - **路径控制**:默认为全局 Node,可根据需要指定特定 Node 路径
6. feat: Overview 面板增强
      - **压缩信息显示**:Overview 面板支持显示请求的 gzip 前后大小对比
      - **数据大小展示**:修复请求和响应内容为空时不显示大小的问题
7. fix: URL 替换修复
      - **路径处理**:修复 URL 替换 `url replacementUrl` 时路径取错的问题
      - **替换准确性**:确保 URL 替换操作准确处理路径参数
8. perf: 性能优化
      - **HTTP2 连接**:优化 HTTP2 session 管理,减少连接创建开销
      - **数据展示**:改进空内容的数据显示逻辑

## v2.0.0
1. feat: **支持 HTTP2 功能**
	> 请确保运行的 Node 版本为 [LTS(>= 10.16.0) 或 Stable(>= 12.12.0) 的最新版本](https://nodejs.org/en/),否则可能会出现一些异常,如:[#24037](https://github.com/nodejs/node/issues/24037)、[#24470](https://github.com/nodejs/node/issues/24470)
2. feat: `**/path/to` 如果 `path/to` 里面包含 `*`,如 `*/cgi-*`,则等价与 `^*/cgi-*`

## v1.17
1. feat: 浏览器和 whistle 之间支持通过 HTTP2 建立连接,(**需要把 [Node](https://nodejs.org) 更新到 `v10.16.0` 及以上版本**)
2. refactor: 调整连接缓存策略,任何连接不做长缓存,减少内存占用

## v1.16
1. feat: 支持插件通过 `options.getRules(cb), options.getValues(cb), options.getCustomCertsInfo(cb)`,分别获取插件 Rules、Values、自定义证书信息
2. feat: HTTPS 菜单的对话框添加 `View Custom Certs` 按钮,用于管理自定义证书
3. feat: 支持通过 `w2 run --inspect` 或 `w2 run --inspectBrk` 开启调试模式
4. feat: 插件列表添加 `Sync` 按钮可用于获取插件的规则或值并设置到界面的Rules或Values
5. feat: 支持通过插件 package.json 配置 `"whistleConfig: { "hintUrl": "/cgi-xxx/xxx" }"`  等方式自定义自动补全列表功能
6. feat: 支持通过 `req.sessionStorage.[get|set|remove]` 实现插件各个server hooks之间的数据传递


## v1.15
1. feat: 支持通过命令行参数 `--socksPort 1080` 启动指定监听端口的 SOCKS v5 服务(目前只支持普通 TCP 请求)
2. feat: 插件server添加了 `req.passThrough()`,`req.request(url/options, cb)`,	`req.writeHead(code, message, headers)` 等方法用于将插件里面的请求转发到指定服务
3. feat: 支持通过命令行参数 `-M rules` 启动无抓包页面模式,这种模式下UI将看不到Network,无法抓包且插件无法通过 `req.getSession(cb)` 获取抓包数据
4. feat: 支持通过 `style://color=!xxx&fontStyle=xxxxx&bgColor=red` 设置请求的字体颜色/样式/背景颜色
5. feat: 支持通过 `enable://proxyFirst` 调整 proxy 配置的优先级高于 host (默认:host > proxy)
6. fix: 修复一些运行过程中遇到的问题


## v1.14
1. feat: 新增协议 [pipe](https://wproxy.org/docs/rules/pipe.html)、[headerReplace](https://wproxy.org/docs/rules/headerReplace.html)
2. fix: `querystring.parse('+')` 自动转转成空格 ' ' 或 `%2B` 问题
3. refactor: 优化启动参数 [--max-http-header-size=size](https://nodejs.org/dist/latest-v10/docs/api/cli.html#cli_max_http_header_size_size) 
4. feat: 新增命令行参数 `--httpPort` 和 `--httpsPort`,分别用于启动普通的 http 和 https server,方便做反向代理,且可用于再启动一个 `http proxy` (跟默认的 http 代理功能一致)和 `https proxy` (可作为https代理服务器) 功能
5. fix: 修复一些运行过程中遇到的问题


## v1.13
1. feat: 优化插件功能,支持 `resRules.txt`
2. feat: 新增协议 [excludeFilter](http://wproxy.org/docs/rules/excludeFilter.html) 和 [includeFilter](http://wproxy.org/docs/rules/includeFilter.html)
3. feat: [log](http://wproxy.org/docs/rules/log.html) 支持注入 `whistle.onWhistleLogSend(level, logStr)` 获取页面日志信息自己做上报
4. feat: 插件支持通过 package.json 配置 `"pluginHomepage": "http://xxx.xxx.com/"` 自定义界面 URL
5. feat: 本地替换新增响应 `206` 功能,支持 iOS 播放本地替换的视频文件
6. feat: 命令行添加 `--no-prev-options` 启动选项,支持通过 `w2 restart` 时不复用先前设置的选项

## v1.12
1. feat: 支持在 `Rules > Settings > The later rules first` 调整规则的优先顺序,默认从上到下,其中Default里面的规则优先级最低,这个设置只对在 Rules 配置的规则生效,对 [reqScript](https://wproxy.org/docs/rules/reqScript.html) 和插件设置的规则不生效
2. feat: 新增协议 [https-proxy](https://wproxy.org/docs/rules/https-proxy.html)
3. feat: [resCookies](https://wproxy.org/docs/rules/resCookies.html) 支持设置 [SameSite](https://www.owasp.org/index.php/SameSite)
4. feat: 支持通过在 Rules 配置 `@url` 或 `@filepath` 或 `@whistle.xxx/path` 加载远程规则
5. feat: 支持通过命令行 `-r, --shadowRules [shadowRules]` 设置 `shadowRules`
6. feat: 支持内嵌 Values
7. feat: 模板字符串支持 `replace`,且支持子匹配
    ```
    pattern protocol://`${search.replace(pattern1,replacment)}`
    www.test.com file://`${search.replace(/Course_(id)\,?/ig,$1cid)}${test.html}`
    ```
    `pattern1` 为正则或普通字符串(不需要加引号)

## v1.11
1. feat: HTTPS 请求自动降级([https://github.com/avwo/whistle/issues/176](https://github.com/avwo/whistle/issues/176))
2. feat: 支持显示HexView(二进制)
3. feat: 新增协议 [xhost](https://wproxy.org/docs/rules/xhost.html)
4. feat: 调整策略,部分协议支持同时匹配多个
5. fix: 修复一些运行过程中遇到的问题

## v1.10
1. feat: 完善界面功能
2. feat: 支持端口匹配 `:12345 operation`
3. feat: 支持设置多个访问webui的域名 `-l "webui1.example.com|webui2.example.com"`
4. feat: 支持通过命令行 `w2 add` 获取当前目录 `.whistle.js` 输出的规则配置,具体参见:[命令行参数](https://wproxy.org/docs/cli.html)
5. feat: 通过 `w2 status [-S storage]` 或 `w2 --all` 显示当前whistle运行状态


## v1.9
1. feat: 支持通过命令行 `-M network` 设置为抓包模式,该模式只能查看抓包不能设置规则及加载插件
2. feat: 支持通过命令行 `-L "script=a.b.com&vase=x.y.com&nohost=imweb.nohost.pro"` 自定义访问插件的域名
3. feat: Composer 支持设置 Rules

## v1.8
1. feat: 新增协议 [htmlPrepend](https://wproxy.org/docs/rules/htmlPrepend.html)、[htmlBody](https://wproxy.org/docs/rules/htmlBody.html)、[htmlAppend](https://wproxy.org/docs/rules/htmlAppend.html)、[cssPrepend](https://wproxy.org/docs/rules/cssPrepend.html)、[cssBody](https://wproxy.org/docs/rules/cssBody.html)、[cssAppend](https://wproxy.org/docs/rules/cssAppend.html)、[jsPrepend](https://wproxy.org/docs/rules/jsPrepend.html)、[jsBody](https://wproxy.org/docs/rules/jsBody.html)、[jsAppend](https://wproxy.org/docs/rules/jsAppend.html)
2. feat: 支持通配符匹配
3. feat: 支持 `Copy As CURL`
4. feat: 支持导入 HAR 文件
5. feat: 支持第三方扩展 Rules 里面的 `@` 符号功能

## v1.7
1. feat: 新增协议 [resScript](https://wproxy.org/docs/rules/resScript.html)、 [responseFor](https://wproxy.org/docs/rules/responseFor.html)、 [resforwardedForScript](https://wproxy.org/docs/rules/forwardedFor.html)
2. fix: 修复一些运行过程中遇到的问题

## v1.6
1. feat: 支持 WebSocket 请求映射,`ws://www.test.com/xxx https://www.abc.com/a/b`
2. feat: 调整证书策略,防止域名里面有不合规的字符,导致 Chrome 出现证书校验失败
3. fix: 修复一些运行过程中遇到的问题

## v1.5
1. feat: Composer 支持构造 WebSocket 和 TCP 请求
2. feat: 支持通过命令行参数 `-P uiPort` 自定义 Whistle 管理界面端口
3. feat: 完善插件功能,支持通过插件的根目录文件 `_values.txt` 设置插件私有的 Values (不支持 `values.txt`),与私有规则 `_rules.txt` 配套使用
4. feat: 界面支持左侧菜单模式,并支持显示请求客户端的端口号和服务器的端口号
5. fix: 修复一些运行过程中遇到的问题

## v1.4
1. feat: 支持通过命令行参数 `-D, -baseDir` 修改 Whistle 存储目录的根路径
2. perf: 优化 `os.networkInterfaces` 的性能
3. fix: 修复一些运行过程中遇到的问题

## v1.3
1. feat: pattern 新增支持无 schema 模式 `//xxx`
2. fix: 修复一些运行过程中遇到的问题

## v1.2
1. feat: 新增协议 [reqScript](https://wproxy.org/docs/rules/reqScript.html)、[ignore](https://wproxy.org/docs/rules/ignore.html)、[enable](https://wproxy.org/docs/rules/enable.html)
2. feat: 完善插件功能,新增 `statsServer`
3. feat: 新增下载根证书短链接 `http://rootca.pro`

## v1.1
1. feat: 新增协议 [pac](https://wproxy.org/docs/rules/pac.html)、[delete](https://wproxy.org/docs/rules/delete.html)、[reqHeaders](https://wproxy.org/docs/rules/reqHeaders.html)、[resHeaders](https://wproxy.org/docs/rules/resHeaders.html)
2. feat: 完善插件功能
3. fix: 修复一些运行过程中遇到的问题

## v1.0
1. feat: 完善插件功能,新增 `tunnelServer`、支持新协议 `whistle.xxx://`
2. feat: 完善 `socks`、`proxy` 协议功能
3. feat: 新增命令行参数 `-l, --localUIHost` 支持修改访问配置页面的域名,默认为 `local.whistlejs.com`
4. feat: 代理请求新增 `x-whistle-policy` 用于设置 Whistle 策略
5. fix: 修复一些运行过程中遇到的问题
6. feat: 替换全新的 Logo,感谢部门的视觉设计同事 **[@wjdgh1031(鬼刀)](https://github.com/wjdgh1031)** 帮忙设计了新logo
7. feat: 完善协议功能 [pathReplace](https://wproxy.org/docs/rules/pathReplace.html)、[log](https://wproxy.org/docs/rules/log.html)、[replaceStatus](https://wproxy.org/docs/rules/replaceStatus.html)、[rawfile](https://wproxy.org/docs/rules/rawfile.html)、[xrawfile](https://wproxy.org/docs/rules/xrawfile.html)、[reqAppend](https://wproxy.org/docs/rules/reqAppend.html)、[resAppend](https://wproxy.org/docs/rules/resAppend.html)、[reqType](https://wproxy.org/docs/rules/reqType.html)、[resType](https://wproxy.org/docs/rules/resType.html)、[reqCharset](https://wproxy.org/docs/rules/reqCharset.html)、[ua](https://wproxy.org/docs/rules/ua.html) 、[reqWriter](https://wproxy.org/docs/rules/reqWriter.html) 、[reqWriterRaw](https://wproxy.org/docs/rules/reqWriterRaw.html) 、[reqReplace](https://wproxy.org/docs/rules/reqReplace.html)、[resReplace](https://wproxy.org/docs/rules/resReplace.html) 等
8. feat: 支持导出抓包数据
9. feat: 支持启动多个实例 `w2 start -S newStorageDir -p newPort`
10. feat: 支持自定义插件
11. fix: 修复一些运行过程中遇到的问题


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2015 avwo

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.



================================================
FILE: README-en_US.md
================================================
<p align="center">
  <a href="https://avwo.github.io/whistle/">
    <img alt="whistle logo" src="https://user-images.githubusercontent.com/11450939/168828068-99e38862-d5fc-42bc-b5ab-6262b2ca27d6.png">
  </a>
</p>

# whistle

[![NPM version](https://img.shields.io/npm/v/whistle.svg?style=flat-square)](https://npmjs.org/package/whistle)
[![node version](https://img.shields.io/badge/node.js-%3E=_8-green.svg?style=flat-square)](http://nodejs.org/download/)
[![npm download](https://img.shields.io/npm/dm/whistle.svg?style=flat-square)](https://npmjs.org/package/whistle)
[![NPM count](https://img.shields.io/npm/dt/whistle.svg?style=flat-square)](https://www.npmjs.com/package/whistle)
[![License](https://img.shields.io/github/license/avwo/whistle?style=flat-square)](https://www.npmjs.com/package/whistle)

[中文](./README.md) · English

Whistle (pronounced /ˈwisəl/) is a cross-platform network debugging and proxy tool built on Node.js. It provides powerful packet capture, request/response inspection and modification, a rule-based modification engine, and extensibility through plugins.

Key features:
1. **Powerful**
   - Capture and modify HTTP, HTTPS, HTTP/2, WebSocket, and TCP traffic
   - Supports HTTP, HTTPS, Socks and reverse proxy modes
   - Built-in tools: Weinre (remote DOM inspection), Console (console logs), Composer (request replay/editing), etc.
2. **Easy to use**
   - Rule-based request/response modification
   - Unified UI for captures, rules, plugins, Weinre/Console/Composer and more
3. **Extensible**
   - SPlugin support for extending rules and UI
   - Can be used as an NPM module in projects
4. **Cross-platform**
   - Supports macOS, Windows, Linux (Ubuntu/Fedora) desktop systems
   - Supports headless Linux server environments

# Installation (recommended)

Desktop users (macOS/Windows/Linux) should use the Whistle client: https://github.com/avwo/whistle-client
> The client skips manual installation and configuration steps

# Headless Linux / Server Install (CLI)

Follow these 4 steps to deploy Whistle on a headless server:

1. Install Whistle (recommended via npm)
   - Install Node.js first: https://nodejs.org/
   - Install: `npm i -g whistle`
      > Alternatively via Homebrew: `brew install whistle`
1. Start Whistle
   - Command: `w2 start`
2. Install CA certificate (required for HTTPS capture)
   - Command: `w2 ca`
   - Manual confirmation may be required:
     - Windows: confirm with “Yes (Y)”
     - macOS: may require entering password or Touch ID
3. Configure proxy
   - Command: `w2 proxy`
   - Specify host:port: `w2 proxy "10.x.x.x:8888"`
   - Disable system proxy: `w2 proxy 0`

Other proxy options:
- Recommended: use a Chrome proxy extension ZeroOmega for easy switching
  > Chrome Web Store (or manual install if blocked): https://chromewebstore.google.com/detail/proxy-switchyomega-3-zero/pfnededegaaopdmhkdmcofjmoldfiped
- Use browser/devtools built-in proxy settings (e.g. Firefox, WeChat DevTools)
- For apps that can't set proxies directly, use Proxifier (Windows/macOS)

# Quick Start

See the official guide for usage and examples: https://wproxy.org/docs/getting-started.html

# Common Commands

- Start: `w2 start`
- Stop: `w2 stop`
- Restart: `w2 restart`
- Status: `w2 status`
- Install CA: `w2 ca`
- Set proxy: `w2 proxy [host:port]` (use `w2 proxy 0` to disable)

# License

[MIT — see the LICENSE file](./LICENSE)


================================================
FILE: README.md
================================================
<p align="center">
  <a href="https://avwo.github.io/whistle/">
    <img alt="whistle logo" src="https://user-images.githubusercontent.com/11450939/168828068-99e38862-d5fc-42bc-b5ab-6262b2ca27d6.png">
  </a>
</p>

# whistle

[![NPM version](https://img.shields.io/npm/v/whistle.svg?style=flat-square)](https://npmjs.org/package/whistle)
[![node version](https://img.shields.io/badge/node.js->=_8-green.svg?style=flat-square)](http://nodejs.org/download/)
[![npm download](https://img.shields.io/npm/dm/whistle.svg?style=flat-square)](https://npmjs.org/package/whistle)
[![NPM count](https://img.shields.io/npm/dt/whistle.svg?style=flat-square)](https://www.npmjs.com/package/whistle)
[![License](https://img.shields.io/github/license/avwo/whistle?style=flat-square)](https://www.npmjs.com/package/whistle)

中文 · [English](./README-en_US.md)

Whistle(发音 /ˈwisəl/)是基于 Node.js 的跨平台网络抓包与调试工具,特点如下:
1. **功能强大**
   - 支持 HTTP、HTTPS、HTTP/2、WebSocket、TCP 的抓包与修改请求/响应
   - 支持 HTTP、HTTPS、Socks、反向代理等多种代理模式
   - 内置常用调试工具:Weinre(远程 DOM 检查)、Console(查看 console 日志)、Composer(请求重放与编辑)等
2. **操作简单**
   - 通过规则配置即可修改请求/响应
   - 提供一站式管理界面:抓包、规则、插件、Weinre/Console/Composer 等集中管理
3. **可扩展**
   - 支持插件扩展规则与界面功能
   - 可作为 NPM 模块在项目中引用
4. **跨平台**
   - 支持 macOS、Windows、Linux(Ubuntu / Fedora)等桌面系统
   - 支持无界面 Linux 服务器环境

# 安装(推荐)

桌面用户(macOS/Windows/Linux)推荐使用 Whistle 客户端:https://github.com/avwo/whistle-client

> 客户端可以免去大部分手动安装与配置步骤

# 无界面 Linux / 服务器 安装(命令行)

按以下 4 步在无界面服务器上快速部署:
1. 安装 Whistle(推荐使用 npm)
   - 需要先安装 Node.js:https://nodejs.org/
   - 安装命令:`npm i -g whistle`
      > 也支持 Homebrew:`brew install whistle`
1. 启动 Whistle
   - 命令:`w2 start`
2. 安装根证书(用于 HTTPS 抓包)
   - 命令:`w2 ca`
   - 安装过程中可能需手动确认:
      - Windows:最后选择 “是 (Y)” 确认
      - macOS:可能需要输入开机密码或 Touch ID 验证
3. 设置代理
   - 命令:`w2 proxy`
   - 设置指定 IP: `w2 proxy "10.x.x.x:8888"`
   - 关闭系统代理: `w2 proxy 0`

其它代理方式:
- 推荐:使用 Chrome 插件 ZeroOmega(便于在浏览器间切换代理)
  > Chrome 商店地址(若无法访问可手动安装):https://chromewebstore.google.com/detail/proxy-switchyomega-3-zero/pfnededegaaopdmhkdmcofjmoldfiped
- 浏览器或开发者工具自带代理设置(例如 Firefox、微信开发者工具)
- 对于无法直接设置代理的应用,可使用 Proxifier(Windows / macOS)

# 快速上手

详细使用指南与示例请查看官方文档:https://wproxy.org/docs/getting-started.html

# 常见命令速查
- 启动:`w2 start`
- 停止:`w2 stop`
- 重启:`w2 restart`
- 查看状态:`w2 status`
- 安装证书:`w2 ca`
- 设置代理:`w2 proxy [host:port]`(`w2 proxy 0` 关闭)

# License

[MIT(详见 LICENSE 文件)](./LICENSE)



================================================
FILE: assets/fiddler/meta.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<Session SID="${SID}">
  <SessionTimers ClientConnected="${ClientConnected}"
   ClientDoneRequest="${ClientDoneRequest}" GatewayTime="${GatewayTime}"
   DNSTime="${DNSTime}" TCPConnectTime="${TCPConnectTime}"
   ServerGotRequest="${ServerGotRequest}"
   ServerBeginResponse="${ServerBeginResponse}"
   ServerDoneResponse="${ServerDoneResponse}"
   ClientBeginResponse="${ClientBeginResponse}"
   ClientDoneResponse="${ClientDoneResponse}" />
  <PipeInfo />
  <SessionFlags>
    <SessionFlag N="x-ttfb" V="${ttfb}" />
    <SessionFlag N="x-processinfo" V="whistle" />
    <SessionFlag N="x-transfer-size" V="${transfer-size}" />
    <SessionFlag N="x-clientip" V="${clientip}" />
    <SessionFlag N="x-ttlb" V="${ttlb}" />
    <SessionFlag N="x-hostip" V="${hostip}" />
    <SessionFlag N="x-clientport" V="${clientport}" />
    <SessionFlag N="x-serverport" V="${serverport}" />
    <SessionFlag N="ui-comments" V="${ui-comments}" />
  </SessionFlags>
</Session>


================================================
FILE: assets/js/log.js
================================================

;(function() {
  if (typeof window === 'undefined' || typeof Image === 'undefined') {
    return;
  }

  if (window._whistleConsole) {
    return;
  }
  var console = window.console = window.console || {};
  var wConsole = window._whistleConsole = {};
  var JSON = window.JSON || patchJSON();
  function patchJSON() {
    var JSON = {};
    var rx_escapable = /[\\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;

    function f(n) {
      return n < 10
              ? '0' + n
              : n;
    }

    function this_value() {
      return this.valueOf();
    }

    if (typeof Date.prototype.toJSON !== 'function') {

      Date.prototype.toJSON = function () {

        return isFinite(this.valueOf())
                  ? this.getUTCFullYear() + '-' +
                          f(this.getUTCMonth() + 1) + '-' +
                          f(this.getUTCDate()) + 'T' +
                          f(this.getUTCHours()) + ':' +
                          f(this.getUTCMinutes()) + ':' +
                          f(this.getUTCSeconds()) + 'Z'
                  : null;
      };

      Boolean.prototype.toJSON = this_value;
      Number.prototype.toJSON = this_value;
      String.prototype.toJSON = this_value;
    }

    var gap,
      indent,
      meta,
      rep;


    function quote(string) {

      rx_escapable.lastIndex = 0;
      return rx_escapable.test(string)
              ? '"' + string.replace(rx_escapable, function (a) {
                var c = meta[a];
                return typeof c === 'string'
                      ? c
                      : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
              }) + '"'
              : '"' + string + '"';
    }


    function str(key, holder) {

      var i,
        k,
        v,
        length,
        mind = gap,
        partial,
        value = holder[key];

      if (value && typeof value === 'object' &&
                  typeof value.toJSON === 'function') {
        value = value.toJSON(key);
      }

      if (typeof rep === 'function') {
        value = rep.call(holder, key, value);
      }

      switch (typeof value) {
      case 'string':
        return quote(value);

      case 'number':

        return isFinite(value)
                  ? String(value)
                  : 'null';

      case 'boolean':
      case 'null':

        return String(value);

      case 'object':

        if (!value) {
          return 'null';
        }

        gap += indent;
        partial = [];

        if (Object.prototype.toString.apply(value) === '[object Array]') {

          length = value.length;
          for (i = 0; i < length; i += 1) {
            partial[i] = str(i, value) || 'null';
          }

          v = partial.length === 0
                      ? '[]'
                      : gap
                          ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
                          : '[' + partial.join(',') + ']';
          gap = mind;
          return v;
        }

        if (rep && typeof rep === 'object') {
          length = rep.length;
          for (i = 0; i < length; i += 1) {
            if (typeof rep[i] === 'string') {
              k = rep[i];
              v = str(k, value);
              if (v) {
                partial.push(quote(k) + (
                                  gap
                                      ? ': '
                                      : ':'
                              ) + v);
              }
            }
          }
        } else {

          for (k in value) {
            if (Object.prototype.hasOwnProperty.call(value, k)) {
              v = str(k, value);
              if (v) {
                partial.push(quote(k) + (
                                  gap
                                      ? ': '
                                      : ':'
                              ) + v);
              }
            }
          }
        }

        v = partial.length === 0
                  ? '{}'
                  : gap
                      ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
                      : '{' + partial.join(',') + '}';
        gap = mind;
        return v;
      }
    }

    if (typeof JSON.stringify !== 'function') {
      meta = {
        '\b': '\\b',
        '\t': '\\t',
        '\n': '\\n',
        '\f': '\\f',
        '\r': '\\r',
        '"': '\\"',
        '\\': '\\\\'
      };
      JSON.stringify = function (value, replacer, space) {

        var i;
        gap = '';
        indent = '';

        if (typeof space === 'number') {
          for (i = 0; i < space; i += 1) {
            indent += ' ';
          }

        } else if (typeof space === 'string') {
          indent = space;
        }

        rep = replacer;
        if (replacer && typeof replacer !== 'function' &&
                      (typeof replacer !== 'object' ||
                      typeof replacer.length !== 'number')) {
          throw new Error('JSON.stringify');
        }


        return str('', {'': value});
      };
    }

    return JSON;
  }

  function stringify(obj) {
    if (typeof obj === 'function') {
      return obj.toString();
    }

    if (obj instanceof Error) {
      var stack = obj.stack;
      if (stack && typeof stack === 'string') {
        if (obj.message && stack.indexOf(obj.message) === -1) {
          return 'Error: ' + obj.message + '\n' + stack;
        }
      }
      return 'Error: ' + obj.message;
    }

    return obj === undefined ? 'undefined' : obj;
  }
  var prefixPath;
  function getPathPrefix() {
    if (prefixPath) {
      return prefixPath;
    }
    prefixPath = window.__WHISTLE_PATH_PREFIX__;
    if (/^\/[\w./-]+$/.test(prefixPath) && prefixPath.length <= 128) {
      var len = prefixPath.length - 1;
      if (prefixPath[len] === '/') {
        prefixPath = prefixPath.substring(0, len);
      }
    } else {
      prefixPath = '';
    }
    return prefixPath;
  }

  var index = 0;
  var MAX_LEN = 1024 * 56;
  function addLog(level, text) {
    var img = new Image();
    var timer;
    if (index > 9999) {
      index = 0;
    }
    var logStr = encodeURIComponent(text && (text + ''));
    if (logStr.length > MAX_LEN) {
      logStr = logStr.substring(0, MAX_LEN);
      var percIndex = logStr.indexOf('%', MAX_LEN - 3);
      if (percIndex !== -1) {
        logStr = logStr.substring(0, percIndex);
      }
    }
    var baseUrl = '$BASE_URL' + getPathPrefix();
    img.src = baseUrl + '$LOG_CGI?id=$LOG_ID&level=' + level + '&text=' + logStr
      + '&t=' + new Date().getTime() + '&' + ++index;
    var preventGC = function() {
      img.onload = img.onerror = null;
      clearTimeout(timer);
    };
    img.onload = img.onerror = preventGC;
    timer = setTimeout(preventGC, 3000);
    if (typeof window.onWhistleLogSend === 'function') {
      window.onWhistleLogSend(level, text);
    }
  }

  function getPageInfo() {
    return '\r\nPage URL: ' + location.href + '\r\nUser Agent: ' + navigator.userAgent;
  }

  function getErrorStack(error, message) {
    var stack = (error.stack || error.message) + '';
    message = message || error.message;
    if (typeof message === 'string') {
      var msg = message.substring(message.indexOf(':') + 1);
      if (stack.indexOf(msg) === -1) {
        stack = message + '\n' + stack;
      }
    }
    return stack + getPageInfo();
  }

  function arrayIndexOf(arr, value) {
    if (arr.indexOf) {
      return arr.indexOf(value);
    }
    for (var i = 0, len = arr.length; i < len; i++) {
      if (arr[i] === value) {
        return i;
      }
    }
    return -1;
  }

  function stringifyObj(obj) {
    if (typeof obj === 'string') {
      return obj;
    }
    try {
      return JSON.stringify(obj);
    } catch(e) {}
    try {
      var keyList = [];
      var valList = [];
      return JSON.stringify(obj, function(key, value) {
        if (value && typeof value === 'object') {
          var index = arrayIndexOf(valList, value);
          valList.push(value);
          keyList.push(key);
          if (index !== -1) {
            return '[Circular ' + keyList[index] + ']';
          }
        }
        return value;
      });
    } catch(e) {}
  }

  var levels = ['fatal', 'error', 'warn', 'info', 'debug', 'log'];
  var noop = function() {};
  var slice = Array.prototype.slice;
  for (var i = 0, len = levels.length; i < len; i++) {
    (function(level) {
      var fn = console[level] || noop;
      var pending;
      var wFn = wConsole[level] = function() {
        var result = slice.call(arguments);
        if (!result.length) {
          result = [undefined];
        }
        if (typeof window.onBeforeWhistleLogSend === 'function') {
          pending = true;
          try {
            window.onBeforeWhistleLogSend(result, level);
          } catch(e) {
            result.push('onBeforeWhistleLogSend' + stringify(e));
          } finally {
            pending = false;
          }
        }
        var len = result.length;
        if (!len) {
          return;
        }
        for (var i = 0; i < len; i++) {
          result[i] = stringify(result[i]);
        }
        result = stringifyObj(result);
        result && addLog(level, result);
      };
      if ($INTERCEPT_CONSOLE) {
        console[level] = function() {
          if (pending) {
            return;
          }
          pending = true;
          var weinreFn = console['_weinre_' + level];
          if (typeof weinreFn === 'function') {
            try {
              weinreFn.apply(this, arguments);
            } catch (e) {}
          }
          wFn.apply(null, arguments);
          try {
            fn.apply(this, arguments);
          } catch(e) {
            fn(arguments.length < 2 ? arguments[0] : slice.apply(arguments));
          } finally {
            pending = false;
          }
        };
      }
    })(levels[i]);
  }
  /*eslint no-console: "off"*/
  var onerror = function(message, filename, lineno, colno, error) {
    if (error) {
      wConsole.error(getErrorStack(error, message));
    } else {
      wConsole.error('Error: ' + message + '(' + filename
          + ':' + lineno + ':' + (colno || 0) + ')' + getPageInfo());
    }
  };
  var isWeinreConsole = function(curConsole) {
    if (curConsole === console || typeof curConsole.log !== 'function') {
      return;
    }
    return curConsole.log.toString().indexOf('this._generic(MessageLevel.Log,') !== -1;
  };
  var attachOnError = function() {
    if (window.onerror !== onerror) {
      window.onerror = onerror;
    }
    var curConsole = window.console;
    if (!curConsole) {
      window.console = console;
    } else if ($INTERCEPT_CONSOLE && isWeinreConsole(curConsole)) {
      for (var i = 0, len = levels.length; i < len; i++) {
        var level = levels[i];
        var fn = console[level];
        var curFn = curConsole[level];
        if (fn !== curFn) {
          console['_weinre_' + level] = curFn;
          curConsole[level] = fn;
        }
      }
    }
    setTimeout(attachOnError, 600);
  };
  attachOnError();

  if (typeof  window.addEventListener === 'function') {
    window.addEventListener('unhandledrejection', function(e) {
      var reason = 'UnhandledRejection';
      if (e) {
         e = stringifyObj(e.reason || e) || String(e);
         reason += (/^[\w.-]*:/.test(e) ? ' ' : ': ') + e;
      }
      wConsole.error(reason);
    });
  }
})();


================================================
FILE: assets/js/weinre.js
================================================

;(function() {
  if (typeof window === 'undefined' || window.WeinreServerURL) {
    return;
  }
  var prefixPath = window.__WHISTLE_PATH_PREFIX__;
  if (/^\/[\w./-]+$/.test(prefixPath) && prefixPath.length <= 128) {
    var len = prefixPath.length - 1;
    if (prefixPath[len] === '/') {
      prefixPath = prefixPath.substring(0, len);
    }
  } else {
    prefixPath = '';
  }
  var baseUrl = '$BASE_URL' + prefixPath;
  window.WeinreServerURL = baseUrl + '$WEINRE_PATH';
  var head = document.head || document.getElementsByTagName('head')[0] || document.documentElement;
  var script = document.createElement('script');
  script.async = true;
  script.charset = 'utf8';
  script.src = baseUrl + '$WEINRE_URL';
  if (head.firstChild) {
    head.insertBefore(script, head.firstChild);
  } else {
    head.appendChild(script);
  }
})();


================================================
FILE: assets/js/worker.js
================================================

var exports = {};
var module = { exports: exports };

;(function() {
  var self = null;
  try {
    (function() {
      /*sourcecode*/
    })();
  } catch (e) {
    setTimeout(function() {
      throw e;
    }, 20);
  }
})();

;(function() {
  !function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return e[r].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){"use strict";function r(e){try{return i(e)}catch(t){}}var o,i=n(1).toByteArray,a=n(2).Base64.decode,s=n(3);if(self.TextDecoder)try{o=new self.TextDecoder("GB18030")}catch(l){}self.getText=function(e){var t=e&&r(e);if(!t)return"";if(!s(t))try{if(o)return o.decode(t)}catch(n){}try{return a(e)}catch(n){}return""}},function(e,t){"use strict";function n(e){var t=e.length;if(t%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var n=e.indexOf("=");-1===n&&(n=t);var r=n===t?0:4-n%4;return[n,r]}function r(e){var t=n(e),r=t[0],o=t[1];return 3*(r+o)/4-o}function o(e,t,n){return 3*(t+n)/4-n}function i(e){var t,r,i=n(e),a=i[0],s=i[1],l=new d(o(e,a,s)),c=0,p=s>0?a-4:a;for(r=0;p>r;r+=4)t=u[e.charCodeAt(r)]<<18|u[e.charCodeAt(r+1)]<<12|u[e.charCodeAt(r+2)]<<6|u[e.charCodeAt(r+3)],l[c++]=t>>16&255,l[c++]=t>>8&255,l[c++]=255&t;return 2===s&&(t=u[e.charCodeAt(r)]<<2|u[e.charCodeAt(r+1)]>>4,l[c++]=255&t),1===s&&(t=u[e.charCodeAt(r)]<<10|u[e.charCodeAt(r+1)]<<4|u[e.charCodeAt(r+2)]>>2,l[c++]=t>>8&255,l[c++]=255&t),l}function a(e){return c[e>>18&63]+c[e>>12&63]+c[e>>6&63]+c[63&e]}function s(e,t,n){for(var r,o=[],i=t;n>i;i+=3)r=(e[i]<<16&16711680)+(e[i+1]<<8&65280)+(255&e[i+2]),o.push(a(r));return o.join("")}function l(e){for(var t,n=e.length,r=n%3,o=[],i=16383,a=0,l=n-r;l>a;a+=i)o.push(s(e,a,a+i>l?l:a+i));return 1===r?(t=e[n-1],o.push(c[t>>2]+c[t<<4&63]+"==")):2===r&&(t=(e[n-2]<<8)+e[n-1],o.push(c[t>>10]+c[t>>4&63]+c[t<<2&63]+"=")),o.join("")}t.byteLength=r,t.toByteArray=i,t.fromByteArray=l;for(var c=[],u=[],d="undefined"!=typeof Uint8Array?Uint8Array:Array,p="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",f=0,g=p.length;g>f;++f)c[f]=p[f],u[p.charCodeAt(f)]=f;u["-".charCodeAt(0)]=62,u["_".charCodeAt(0)]=63},function(e,t,n){var r,o;(function(n){!function(t,n){e.exports=n(t)}("undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof n?n:this,function(n){"use strict";n=n||{};var i,a=n.Base64,s="2.6.4",l="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",c=function(e){for(var t={},n=0,r=e.length;r>n;n++)t[e.charAt(n)]=n;return t}(l),u=String.fromCharCode,d=function(e){if(e.length<2){var t=e.charCodeAt(0);return 128>t?e:2048>t?u(192|t>>>6)+u(128|63&t):u(224|t>>>12&15)+u(128|t>>>6&63)+u(128|63&t)}var t=65536+1024*(e.charCodeAt(0)-55296)+(e.charCodeAt(1)-56320);return u(240|t>>>18&7)+u(128|t>>>12&63)+u(128|t>>>6&63)+u(128|63&t)},p=/[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g,f=function(e){return e.replace(p,d)},g=function(e){var t=[0,2,1][e.length%3],n=e.charCodeAt(0)<<16|(e.length>1?e.charCodeAt(1):0)<<8|(e.length>2?e.charCodeAt(2):0),r=[l.charAt(n>>>18),l.charAt(n>>>12&63),t>=2?"=":l.charAt(n>>>6&63),t>=1?"=":l.charAt(63&n)];return r.join("")},h=n.btoa&&"function"==typeof n.btoa?function(e){return n.btoa(e)}:function(e){if(e.match(/[^\x00-\xFF]/))throw new RangeError("The string contains invalid characters.");return e.replace(/[\s\S]{1,3}/g,g)},m=function(e){return h(f(String(e)))},A=function(e){return e.replace(/[+\/]/g,function(e){return"+"==e?"-":"_"}).replace(/=/g,"")},M=function(e,t){return t?A(m(e)):m(e)},w=function(e){return M(e,!0)};n.Uint8Array&&(i=function(e,t){for(var n="",r=0,o=e.length;o>r;r+=3){var i=e[r],a=e[r+1],s=e[r+2],c=i<<16|a<<8|s;n+=l.charAt(c>>>18)+l.charAt(c>>>12&63)+("undefined"!=typeof a?l.charAt(c>>>6&63):"=")+("undefined"!=typeof s?l.charAt(63&c):"=")}return t?A(n):n});var b,y=/[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}/g,v=function(e){switch(e.length){case 4:var t=(7&e.charCodeAt(0))<<18|(63&e.charCodeAt(1))<<12|(63&e.charCodeAt(2))<<6|63&e.charCodeAt(3),n=t-65536;return u((n>>>10)+55296)+u((1023&n)+56320);case 3:return u((15&e.charCodeAt(0))<<12|(63&e.charCodeAt(1))<<6|63&e.charCodeAt(2));default:return u((31&e.charCodeAt(0))<<6|63&e.charCodeAt(1))}},T=function(e){return e.replace(y,v)},x=function(e){var t=e.length,n=t%4,r=(t>0?c[e.charAt(0)]<<18:0)|(t>1?c[e.charAt(1)]<<12:0)|(t>2?c[e.charAt(2)]<<6:0)|(t>3?c[e.charAt(3)]:0),o=[u(r>>>16),u(r>>>8&255),u(255&r)];return o.length-=[0,0,2,1][n],o.join("")},N=n.atob&&"function"==typeof n.atob?function(e){return n.atob(e)}:function(e){return e.replace(/\S{1,4}/g,x)},C=function(e){return N(String(e).replace(/[^A-Za-z0-9\+\/]/g,""))},I=function(e){return T(N(e))},E=function(e){return String(e).replace(/[-_]/g,function(e){return"-"==e?"+":"/"}).replace(/[^A-Za-z0-9\+\/]/g,"")},D=function(e){return I(E(e))};n.Uint8Array&&(b=function(e){return Uint8Array.from(C(E(e)),function(e){return e.charCodeAt(0)})});var L=function(){var e=n.Base64;return n.Base64=a,e};if(n.Base64={VERSION:s,atob:C,btoa:h,fromBase64:D,toBase64:M,utob:f,encode:M,encodeURI:w,btou:T,decode:D,noConflict:L,fromUint8Array:i,toUint8Array:b},"function"==typeof Object.defineProperty){var S=function(e){return{value:e,enumerable:!1,writable:!0,configurable:!0}};n.Base64.extendString=function(){Object.defineProperty(String.prototype,"fromBase64",S(function(){return D(this)})),Object.defineProperty(String.prototype,"toBase64",S(function(e){return M(this,e)})),Object.defineProperty(String.prototype,"toBase64URI",S(function(){return M(this,!0)}))}}return n.Meteor&&(Base64=n.Base64),"undefined"!=typeof e&&e.exports?e.exports.Base64=n.Base64:(r=[],o=function(){return n.Base64}.apply(t,r),!(void 0!==o&&(e.exports=o))),{Base64:n.Base64}})}).call(t,function(){return this}())},function(e,t){"use strict";function n(e,t){t=t||0;for(var n=Math.min(e.length,r);n>t;t++){var o=e[t];if(!(9==o||10==o||13==o||o>=32&&127>=o)){++t;var i=e[t];if(o>=194&&223>=o){if(i>=128&&191>=i)continue;return!i}++t;var a=e[t];if(224==o){if(i>=160&&191>=i&&a>=128&&191>=a)continue;return!a}if(o>=225&&236>=o||238==o||239==o){if(i>=128&&191>=i&&a>=128&&191>=a)continue;return!a}if(237==o){if(i>=128&&159>=i&&a>=128&&191>=a)continue;return!a}++t;var s=e[t];if(240==o){if(i>=144&&191>=i&&a>=128&&191>=a&&s>=128&&191>=s)continue;return!s}if(o>=241&&243>=o){if(i>=128&&191>=i&&a>=128&&191>=a&&s>=128&&191>=s)continue;return!s}if(244==o){if(i>=128&&143>=i&&a>=128&&191>=a&&s>=128&&191>=s)continue;return!s}return!1}}return!0}var r=32768;e.exports=function(e){return n(e)?!0:0===e[0]&&n(e,5)}}]);

  var getText = function(obj) {
    return self.getText(obj.base64);
  };
  var parseJson = function(str) {
    if (!str || !/^(?:\{[\s\S]*\}|\[[\s\S]*\])$/) {
      return;
    }
    try {
      return JSON.parse(str);
    } catch (e) {}
  };

  var defineProps = function (obj) {
    if (Object.defineProperties) {
      var body, json;
      var getBody = function () {
        if (body === undefined) {
          body = getText(obj);
        }
        return body;
      };
      Object.defineProperties(obj, {
        body: {  get: getBody  },
        json: {
          get: function () {
            if (json === undefined) {
              json = parseJson(getBody()) || null;
            }
            return json;
          }
        }
      });
    } else {
      obj.body = getText(obj) || '';
      obj.json = parseJson(obj) || null;
    }
    return obj;
  };
  var handle = module.exports;
  if (typeof handle !== 'function') {
    handle = null;
  }

  self.onmessage = function(e) {
    var data = handle && e.data;
    var id = data && data.id;
    if (!id) {
      return;
    }
    data.res = defineProps(data.res || {});
    data.req = defineProps(data.req || {});
    data.req.headers = data.req.headers || {};
    data.res.headers = data.res.headers || {};
    handle(data, function(result) {
      result && self.postMessage({
        id: id,
        plugin: '$PLUGIN_NAME',
        data: result
      });
    });
  };
})();

self.postMessage(true);



================================================
FILE: assets/menu.html
================================================
<style>html {background: #fff;}</style>
<script>
  ;(function() {
    var config = window.whistleMenuConfig;
    var list = [];
    var networkListeners = [];
    var rulesListeners = [];
    var valuesListeners = [];
    var pluginsListeners = [];
    var handleOnLoad = function() {
      timer = null;
      list.forEach(emit);
      list = null;
    };
    var timer = setTimeout(handleOnLoad, 12000);

    function execListeners(listeners, options) {
      listeners.forEach(function(fn) {
        try {
          fn(options)
        } catch (e) {
          console.error(e);
        }
      });
    }

    function emit(options) {
      switch(options.type) {
        case 'rules':
          execListeners(rulesListeners, options);
          break;
        case 'values':
          execListeners(valuesListeners, options);
          break;
        case 'plugins':
          execListeners(pluginsListeners, options);
          break;
        default:
          execListeners(networkListeners, options);
      }
    }
    window.onWhistleContextMenuClick = function(options) {
      if (list) {
        list.push(options);
      } else {
        emit(options);
      }
    };
    var delayOnLoad = function() {
      if (timer) {
        setTimeout(handleOnLoad, 100);
        clearTimeout(timer);
        timer = null;
      }
    };
    window.onload = delayOnLoad;
    try {
      window.addEventListener('load', delayOnLoad);
    } catch (e) {}
    var toast = {};
    var addNetworkListener = function(l) {
      if (typeof l === 'function' && networkListeners.indexOf(l) === -1) {
        networkListeners.push(l);
      }
    };
    var removeNetworkListener = function(l) {
      l = networkListeners.indexOf(l);
      if (l !== -1) {
        networkListeners.splice(l, 1);
      }
    };
    var removeAllNetworkListeners = function() {
      networkListeners = [];
    };
    var addRulesListener = function(l) {
      if (typeof l === 'function' && rulesListeners.indexOf(l) === -1) {
        rulesListeners.push(l);
      }
    };
    var removeRulesListener = function(l) {
      l = rulesListeners.indexOf(l);
      if (l !== -1) {
        rulesListeners.splice(l, 1);
      }
    };
    var removeAllRulesListeners = function() {
      rulesListeners = [];
    };
    var addValuesListener = function(l) {
      if (typeof l === 'function' && valuesListeners.indexOf(l) === -1) {
        valuesListeners.push(l);
      }
    };
    var removeValuesListener = function(l) {
      l = valuesListeners.indexOf(l);
      if (l !== -1) {
        valuesListeners.splice(l, 1);
      }
    };
    var removeAllValuesListeners = function() {
      valuesListeners = [];
    };
    var addPluginsListener = function(l) {
      if (typeof l === 'function' && pluginsListeners.indexOf(l) === -1) {
        pluginsListeners.push(l);
      }
    };
    var removePluginsListener = function(l) {
      l = pluginsListeners.indexOf(l);
      if (l !== -1) {
        pluginsListeners.splice(l, 1);
      }
    };
    var removeAllPluginsListeners = function(l) {
      pluginsListeners = [];
    };

    function on(type, l) {
      if (typeof l !== 'function') {
        return;
      }
      switch(type) {
        case 'network':
          return addNetworkListener(l);
        case 'rules':
          return addRulesListener(l);
        case 'values':
          return addValuesListener(l);
        case 'plugins':
          return addPluginsListener(l);
      }
    }

    function off(type, l) {
      switch(type) {
        case 'network':
          if (l) {
            removeNetworkListener(l);
          } else {
            removeAllNetworkListeners();
          }
          return;
        case 'rules':
          if (l) {
            removeRulesListener(l);
          } else {
            removeAllRulesListeners();
          }
          return;
        case 'values':
          if (l) {
            removeValuesListener(l);
          } else {
            removeAllValuesListeners();
          }
          return;
        case 'plugins':
          if (l) {
            removePluginsListener(l);
          } else {
            removeAllPluginsListeners();
          }
          return;
      }
    }

    var whistleBridge = {
      config: config,
      toast: toast,
      on: on,
      off: off,
      addNetworkListener: addNetworkListener,
      removeNetworkListener: removeNetworkListener,
      removeAllNetworkListeners: removeAllNetworkListeners,
      addRulesListener: addRulesListener,
      removeRulesListener: removeRulesListener,
      removeAllRulesListeners: removeAllRulesListeners,
      addValuesListener: addValuesListener,
      removeValuesListener: removeValuesListener,
      removeAllValuesListeners: removeAllValuesListeners,
      addPluginsListener: addPluginsListener,
      removePluginsListener: removePluginsListener,
      removeAllPluginsListeners: removeAllPluginsListeners
    };
    try {
      window.initWhistleBridge = function(options) {
        window.initWhistleBridge = function() {};
        Object.keys(options.msgBox).forEach(function(name) {
          toast[name] = options.msgBox[name];
        });
        whistleBridge.getSelectedSessionList = options.getSelectedSessionList;
        whistleBridge.getActiveSession = whistleBridge.getSession = whistleBridge.getSelectedSession = options.getActiveSession;
        whistleBridge.showOption = options.showOption;
        whistleBridge.hideOption = options.hideOption;
        whistleBridge.updateUI = options.updateUI;
        whistleBridge.copyText = options.copyText;
        whistleBridge.pageId = options.pageId;
        whistleBridge.compose = options.compose;
        whistleBridge.composeInterrupt = options.createComposeInterrupt();
        whistleBridge.getWhistleId = options.getWhistleId;
        whistleBridge.hasWhistleToken = options.hasWhistleToken;
        whistleBridge.decodeBase64 = options.decodeBase64;
        whistleBridge.joinBase64 = options.joinBase64;
        whistleBridge.getReqId = options.getReqId;
        whistleBridge.onComposeData = options.onComposeData;
        whistleBridge.offComposeData = options.offComposeData;
        whistleBridge.importSessions = options.importSessions;
        whistleBridge.exportSessions = options.exportSessions;
        whistleBridge.importMockData = options.importMockData;
        whistleBridge.download = options.download;
        whistleBridge.setNetworkSettings = options.setNetworkSettings;
        whistleBridge.setRulesSettings = options.setRulesSettings;
        whistleBridge.setValuesSettings = options.setValuesSettings;
        whistleBridge.setComposerData = options.setComposerData;
        whistleBridge.showHttpsSettings = options.showHttpsSettings;
        whistleBridge.showCustomCerts = options.showCustomCerts;
        whistleBridge.uploadCustomCerts = options.uploadCustomCerts;
        whistleBridge.showNetwork = options.showNetwork;
        whistleBridge.showRules = options.showRules;
        whistleBridge.showValues = options.showValues;
        whistleBridge.showPlugins = options.showPlugins;
        whistleBridge.showService = options.showService;
        whistleBridge.hideService = options.hideService;
        whistleBridge.getInstalledPlugins = options.getInstalledPlugins;
        whistleBridge.showInstallPlugins = options.showInstallPlugins;
        whistleBridge.showUpdatePlugins = options.showUpdatePlugins;
        whistleBridge.readFileAsText = options.readFileAsText;
        whistleBridge.readFileAsBase64 = options.readFileAsBase64;
        whistleBridge.getVersion = options.getVersion;
        whistleBridge.request = options.request;
        whistleBridge.createRequest = options.createRequest;
        whistleBridge.parseRules = options.parseRules;
        whistleBridge.showModal = options.showModal;
        whistleBridge.createModal = options.createModal;
        whistleBridge.importRules = options.importRules;
        whistleBridge.importValues = options.importValues;
        whistleBridge.getServerInfo = options.getServerInfo;
        whistleBridge.alert = options.alert;
        whistleBridge.confirm = options.confirm;
        whistleBridge.syncData = options.syncData;
        whistleBridge.syncRules = options.syncRules;
        whistleBridge.syncValues = options.syncValues;
      };
      window.parent.onPluginContextMenuReady(window);
    } catch (e) {}
    window.whistleBridge = whistleBridge;
  })();
</script>


================================================
FILE: assets/modal.html
================================================
<!DOCTYPE html>
<style>html {background: #fff;}</style>
<script>
  ;(function() {
    var toast = {};
    var whistleBridge = {
      toast: toast
    };
    try {
      window.parent.onWhistlePluginOptionModalReady(function(options) {
        Object.keys(options.msgBox).forEach(function(name) {
          toast[name] = options.msgBox[name];
        });
        whistleBridge.getSelectedSessionList = options.getSelectedSessionList;
        whistleBridge.getActiveSession = whistleBridge.getSession = whistleBridge.getSelectedSession = options.getActiveSession;
        whistleBridge.showOption = options.showOption;
        whistleBridge.hideOption = options.hideOption;
        whistleBridge.updateUI = options.updateUI;
        whistleBridge.copyText = options.copyText;
        whistleBridge.pageId = options.pageId;
        whistleBridge.compose = options.compose;
        whistleBridge.composeInterrupt = options.createComposeInterrupt();
        whistleBridge.getWhistleId = options.getWhistleId;
        whistleBridge.hasWhistleToken = options.hasWhistleToken;
        whistleBridge.decodeBase64 = options.decodeBase64;
        whistleBridge.joinBase64 = options.joinBase64;
        whistleBridge.getReqId = options.getReqId;
        whistleBridge.onComposeData = options.onComposeData;
        whistleBridge.offComposeData = options.offComposeData;
        whistleBridge.importSessions = options.importSessions;
        whistleBridge.exportSessions = options.exportSessions;
        whistleBridge.importMockData = options.importMockData;
        whistleBridge.download = options.download;
        whistleBridge.setNetworkSettings = options.setNetworkSettings;
        whistleBridge.setRulesSettings = options.setRulesSettings;
        whistleBridge.setValuesSettings = options.setValuesSettings;
        whistleBridge.setComposerData = options.setComposerData;
        whistleBridge.showHttpsSettings = options.showHttpsSettings;
        whistleBridge.showCustomCerts = options.showCustomCerts;
        whistleBridge.uploadCustomCerts = options.uploadCustomCerts;
        whistleBridge.showNetwork = options.showNetwork;
        whistleBridge.showRules = options.showRules;
        whistleBridge.showValues = options.showValues;
        whistleBridge.showPlugins = options.showPlugins;
        whistleBridge.showService = options.showService;
        whistleBridge.hideService = options.hideService;
        whistleBridge.getInstalledPlugins = options.getInstalledPlugins;
        whistleBridge.showInstallPlugins = options.showInstallPlugins;
        whistleBridge.showUpdatePlugins = options.showUpdatePlugins;
        whistleBridge.readFileAsText = options.readFileAsText;
        whistleBridge.readFileAsBase64 = options.readFileAsBase64;
        whistleBridge.getVersion = options.getVersion;
        whistleBridge.request = options.request;
        whistleBridge.createRequest = options.createRequest;
        whistleBridge.parseRules = options.parseRules;
        whistleBridge.showModal = options.showModal;
        whistleBridge.importRules = options.importRules;
        whistleBridge.importValues = options.importValues;
        whistleBridge.getServerInfo = options.getServerInfo;
        whistleBridge.alert = options.alert;
        whistleBridge.confirm = options.confirm;
        whistleBridge.syncData = options.syncData;
        whistleBridge.syncRules = options.syncRules;
        whistleBridge.syncValues = options.syncValues;
      }, window);
    } catch (e) {}
    window.whistleBridge = whistleBridge;
  })();
</script>


================================================
FILE: assets/tab.html
================================================
<style>html {background: #fff;}</style>
<script>
  ;(function() {
    var config = window.whistleInspectorConfig;
    var activeList = [];
    var stateList = [1];
    var getActiveSession;
    var getSelectedSessionList;
    var listenersList = [];
    var frameChangeListeners = [];
    var composeListeners = [];
    var tabChangeListeners = [];
    var curFrames = null;
    var firstFrame;
    var lastFrame;
    var selected = true;
    var composerItem;
    var frameTimer;

    function initState(flag) {
      stateList[1] = flag;
      stateList[2] = flag;
      stateList[3] = flag;
    }

    function updateState(item) {
      if (!item || item.lost || item.endTime) {
        return  initState(1);
      }
      initState();
      if (item.responseTime) {
        stateList[2] = 1;
      }
      if (item.requestTime) {
        stateList[1] = 1;
      }
    }

    function emitTabChange(_selected) {
      if (selected !== _selected) {
        selected = _selected;
        tabChangeListeners.forEach(function(l) {
          l(selected);
        });
      }
    }

    function emitFrameChange() {
      var curItem = getActiveSession();
      var frames = curItem && curItem.frames || null;
      var hasChanged;
      var listenersLen = frameChangeListeners.length;
      if (curFrames !== frames) {
        curFrames = frames;
        hasChanged = listenersLen;
      } else if (curFrames && listenersLen) {
        var curLen = curFrames.length;
        var len = frames.length;
        hasChanged = curLen !== len || firstFrame != frames[0] || lastFrame != frames[len - 1];
      }
      if (hasChanged) {
        if (curFrames) {
          firstFrame = curFrames[0];
          lastFrame = curFrames[curFrames.length - 1];
        } else {
          firstFrame = lastFrame = undefined;
        }
        frameChangeListeners.forEach(function(l) {
          l(curFrames);
        });
      }
      frameTimer = setTimeout(emitFrameChange, 1000);
    }

    function emitListeners(item, state) {
      if (stateList[state] && item !== activeList[state]) {
        activeList[state] = item;
        var listeners = listenersList[state];
        listeners.forEach(function(l) {
          l(item);
        });
      }
    }

    function emitAll(item, hide, comItem) {
      if (comItem) {
        composerItem = comItem;
        composeListeners.forEach(function(l) {
          l(comItem);
        });
        return;
      }
      if (frameTimer) {
        clearTimeout(frameTimer);
        frameTimer = null;
      }
      if (hide) {
        return emitTabChange(false);
      }
      emitTabChange(true);
      updateState(item);
      emitListeners(item, 0);
      emitListeners(item, 1);
      emitListeners(item, 2);
      emitListeners(item, 3);
      emitFrameChange();
    }

    window.__pushWhistle5b6af7b9884e1165SessionActive__ = emitAll;

    function getAddEventHandler(state) {
      state = state || 0;
      listenersList[state] = [];
      return function(l) {
        if (typeof l !== 'function') {
          return;
        }
        var item = getActiveSession();
        emitAll(item);
        activeList[state] = item;
        if (stateList[state]) {
          l(item);
        }
        var listeners = listenersList[state];
        listeners.indexOf(l) === -1 && listeners.push(l);
      };
    }

    function getRemoveEventListener(state) {
      state = state || 0;
      return function(l) {
        var listeners = listenersList[state];
        var index = listeners.indexOf(l);
        index !== -1 && listeners.splice(index, 1);
      };
    }

    function getRemoveEventListeners(state) {
      state = state || 0;
      return function(l) {
        listenersList[state] = [];
      };
    }

    var toast = {};
    var addSessionActiveListener = getAddEventHandler();
    var removeSessionActiveListener = getRemoveEventListener();
    var removeSessionActiveListeners = getRemoveEventListeners();
    var addSessionRequestListener = getAddEventHandler(1);
    var removeSessionRequestListener = getRemoveEventListener(1);
    var removeSessionRequestListeners = getRemoveEventListeners(1);
    var addSessionResponseListener = getAddEventHandler(2);
    var removeSessionResponseListener = getRemoveEventListener(2);
    var removeSessionResponseListeners = getRemoveEventListeners(2);
    var addSessionCompleteListener = getAddEventHandler(3);
    var removeSessionCompleteListener = getRemoveEventListener(3);
    var removeSessionCompleteListeners = getRemoveEventListeners(3);

    function on(type, l) {
      if (typeof l !== 'function') {
        return;
      }
      switch(type) {
        case 'sessionActive':
          return addSessionActiveListener(l);
        case 'sessionRequest':
          return addSessionRequestListener(l);
        case 'sessionResponse':
          return addSessionResponseListener(l);
        case 'sessionComplete':
          return addSessionCompleteListener(l);
        case 'tabChange':
          if (tabChangeListeners.indexOf(l) === -1) {
            tabChangeListeners.push(l);
          }
          return;
        case 'frameChange':
          if (frameChangeListeners.indexOf(l) === -1) {
            frameChangeListeners.push(l);
          }
          return;
        case 'compose':
          if (composeListeners.indexOf(l) === -1) {
            composeListeners.push(l);
          }
           composerItem && l(composerItem);
          return;
      }
    }

    function off(type, l) {
      switch(type) {
        case 'sessionActive':
          if (l) {
            removeSessionActiveListener(l);
          } else {
            removeSessionActiveListeners();
          }
          return;
        case 'sessionRequest':
          if (l) {
            removeSessionRequestListener(l);
          } else {
            removeSessionRequestListeners();
          }
          return;
        case 'sessionResponse':
          if (l) {
            removeSessionResponseListener(l);
          } else {
            removeSessionResponseListeners();
          }
          return;
        case 'sessionComplete':
          if (l) {
            removeSessionCompleteListener(l);
          } else {
            removeSessionCompleteListeners();
          }
          return;
        case 'tabChange':
          if (l) {
            var index = tabChangeListeners.indexOf(l);
            if (index !== -1) {
              tabChangeListeners.splice(index, 1);
            }
          } else {
            tabChangeListeners = [];
          }
          return;
        case 'frameChange':
          if (l) {
            var index = frameChangeListeners.indexOf(l);
            if (index !== -1) {
              frameChangeListeners.splice(index, 1);
            }
          } else {
            frameChangeListeners = [];
          }
          return;
        case 'compose':
          if (l) {
            var index = composeListeners.indexOf(l);
            if (index !== -1) {
              composeListeners.splice(index, 1);
            }
          } else {
            composeListeners = [];
          }
          return;
      }
    }

    var whistleBridge = {
      config: config,
      toast: toast,
      on: on,
      off: off,
      isSelected: function() {
        return selected;
      },
      getFrames: function() {
        return curFrames;
      },
      addSessionActiveListener: addSessionActiveListener,
      removeSessionActiveListener: removeSessionActiveListener,
      removeSessionActiveListeners: removeSessionActiveListeners,
      addSessionRequestListener: addSessionRequestListener,
      removeSessionRequestListener: removeSessionRequestListener,
      removeSessionRequestListeners: removeSessionRequestListeners,
      addSessionResponseListener: addSessionResponseListener,
      removeSessionResponseListener: removeSessionResponseListener,
      removeSessionResponseListeners: removeSessionResponseListeners,
      addSessionCompleteListener: addSessionCompleteListener,
      removeSessionCompleteListener: removeSessionCompleteListener,
      removeSessionCompleteListeners: removeSessionCompleteListeners
    };

    try {
      window.parent.onWhistleInspectorCustomTabReady(function(options) {
        Object.keys(options.msgBox).forEach(function(name) {
          toast[name] = options.msgBox[name];
        });
        getActiveSession = options.getActiveSession;
        getSelectedSessionList = options.getSelectedSessionList;
        whistleBridge.showOption = options.showOption;
        whistleBridge.hideOption = options.hideOption;
        whistleBridge.updateUI = options.updateUI;
        whistleBridge.copyText = options.copyText;
        whistleBridge.pageId = options.pageId;
        whistleBridge.compose = options.compose;
        whistleBridge.composeInterrupt = options.createComposeInterrupt();
        whistleBridge.getWhistleId = options.getWhistleId;
        whistleBridge.hasWhistleToken = options.hasWhistleToken;
        whistleBridge.decodeBase64 = options.decodeBase64;
        whistleBridge.joinBase64 = options.joinBase64;
        whistleBridge.getReqId = options.getReqId;
        whistleBridge.onComposeData = options.onComposeData;
        whistleBridge.offComposeData = options.offComposeData;
        whistleBridge.importSessions = options.importSessions;
        whistleBridge.exportSessions = options.exportSessions;
        whistleBridge.importMockData = options.importMockData;
        whistleBridge.download = options.download;
        whistleBridge.setNetworkSettings = options.setNetworkSettings;
        whistleBridge.setRulesSettings = options.setRulesSettings;
        whistleBridge.setValuesSettings = options.setValuesSettings;
        whistleBridge.setComposerData = options.setComposerData;
        whistleBridge.showHttpsSettings = options.showHttpsSettings;
        whistleBridge.showCustomCerts = options.showCustomCerts;
        whistleBridge.uploadCustomCerts = options.uploadCustomCerts;
        whistleBridge.showNetwork = options.showNetwork;
        whistleBridge.showRules = options.showRules;
        whistleBridge.showValues = options.showValues;
        whistleBridge.showPlugins = options.showPlugins;
        whistleBridge.showService = options.showService;
        whistleBridge.hideService = options.hideService;
        whistleBridge.getInstalledPlugins = options.getInstalledPlugins;
        whistleBridge.showInstallPlugins = options.showInstallPlugins;
        whistleBridge.showUpdatePlugins = options.showUpdatePlugins;
        whistleBridge.readFileAsText = options.readFileAsText;
        whistleBridge.readFileAsBase64 = options.readFileAsBase64;
        whistleBridge.getVersion = options.getVersion;
        whistleBridge.request = options.request;
        whistleBridge.createRequest = options.createRequest;
        whistleBridge.parseRules = options.parseRules;
        whistleBridge.showModal = options.showModal;
        whistleBridge.getSelectedSessionList = getSelectedSessionList;
        whistleBridge.getActiveSession = whistleBridge.getSession = whistleBridge.getSelectedSession = getActiveSession;
        whistleBridge.importRules = options.importRules;
        whistleBridge.importValues = options.importValues;
        whistleBridge.getServerInfo = options.getServerInfo;
        whistleBridge.alert = options.alert;
        whistleBridge.confirm = options.confirm;
        whistleBridge.syncData = options.syncData;
        whistleBridge.syncRules = options.syncRules;
        whistleBridge.syncValues = options.syncValues;
      }, window);
    } catch (e) {}
    window.whistleBridge = whistleBridge;
  })();
</script>


================================================
FILE: bin/ca/cli.js
================================================
var net = require('net');
var fs = require('fs');
var path = require('path');
var installRootCA = require('./index');
var util = require('../util');
var fileMgr = require('../../lib/util/file-mgr');
var httpMgr = require('../../lib/util/http-mgr');
var commonUtil = require('../../lib/util/common');
var config = require('../../lib/config');

var NUM_RE = /^\d+$/;
var HOST_SUFFIX_RE = /\:(\d+|auto)?$/;
var HOST_RE = /^[a-z\d_-]+(?:\.[a-z\d_-]+)*$/i;
var MAX_LEN = 1024 * 1024;

function installCert(certFile, url) {
  try {
    installRootCA(fileMgr.convertSlash(certFile));
    util.info('Successfully installed Root CA from (' + (url || certFile) + ')');
  } catch (e) {
    util.error('Certificate installation failed: ' + e.message);
  }
}

function install(addr, useDefault) {
  if (addr.file) {
    return installCert(addr.file);
  }
  addr.needRawData = true;
  addr.maxLength = MAX_LEN;
  addr.headers = {
    'user-agent': config.appName + '/' + config.version
  };
  httpMgr.request(addr, function(err, body, res) {
    if (err) {
      if (useDefault && err.code === 'ECONNREFUSED') {
        return installCert(path.join(commonUtil.getWhistlePath(), '.whistle/certs/root.crt'));
      }
      return util.error(err.message);
    }
    if (res.statusCode != 200) {
      return util.error('Bad response (' + res.statusCode + ')');
    }
    if (!body || !body.length) {
      return util.error('Empty certificate content');
    }
    var tempFile = path.join(commonUtil.getWhistlePath(), Date.now() + '-' + util.getHash(addr.url) + '.crt');
    fs.writeFileSync(tempFile, body);
    installCert(tempFile, addr.url);
    fs.unlinkSync(tempFile);
  });
}

module.exports = function(argv) {
  var options = {};
  argv.forEach(function(arg) {
    if (NUM_RE.test(arg)) {
      delete options.addr;
      options.port = parseInt(arg, 10) || options.port;
    } else if (net.isIP(arg)) {
      delete options.addr;
      options.host = arg || options.host;
    } else if (HOST_SUFFIX_RE.test(arg)) {
      delete options.port;
      delete options.addr;
      var port = RegExp.$1;
      if (port > 0) {
        options.port = parseInt(port, 10) || options.port;
      }
      var host = arg.slice(0, - port.length - 1);
      if (host[0] === '[') {
        host = host.substring(1);
      }
      var lastIndex = host.length - 1;
      if (host[lastIndex] === ']') {
        host = host.substring(0, lastIndex);
      }
      if (host && (net.isIP(host) || HOST_RE.test(host))) {
        options.host = host || options.host;
      }
    } else {
      delete options.port;
      delete options.host;
      if (commonUtil.isUrl(arg)) {
        options.addr = { url: arg };
      } else {
        options.addr = { file: arg };
      }
    }
  });
  if (!options.addr) {
    var host = options.host || '127.0.0.1';
    var port = options.port || util.getDefaultPort();
    options.addr = { url: 'http://' + util.joinIpPort(host, + port) + '/cgi-bin/rootca' };
  }
  var url = options.addr && options.addr.url;
  if (url) {
    options.addr.url = url.replace(/#.*$/, '') + (url.indexOf('?') === -1 ? '?' : '&') + 'enableHttps=1';
  }
  install(options.addr, !options.host && !options.port);
};


================================================
FILE: bin/ca/index.d.ts
================================================
export default function (certFile: String): void;


================================================
FILE: bin/ca/index.js
================================================
var cp = require('child_process');
var fs = require('fs');
var common = require('../../lib/util/common');

var spawnSync = cp.spawnSync;
var execSync = cp.execSync;

function checkSuccess(result) {
  var stderr = result.stderr;
  if (stderr && stderr.length) {
    throw new Error(stderr + '');
  }
}

function getKeyChain() {
  var result = spawnSync('security', ['default-keychain']);
  checkSuccess(result);
  return (result.stdout + '').split('"')[1];
}

function installMac(certPath) {
  var result = spawnSync('security', ['add-trusted-cert', '-k', getKeyChain(), certPath]);
  checkSuccess(result);
  var msg = result.stdout + '';
  if (/Error:/i.test(msg)) {
    throw new Error(msg);
  }
}


function installWin(certFile) {
  var result = spawnSync('certutil', ['-addstore', '-user', 'Root', certFile]);
  checkSuccess(result);
  if (/ERROR_CANCELLED/i.test(result.stdout + '')) {
    throw new Error('The authorization was canceled by the user');
  }
}

var UBUNTU_CA_DIR = '/usr/local/share/ca-certificates/';
var FEDORA_CA_DIR = '/etc/pki/ca-trust/source/anchors/';

function getCAConfig() {
  var stats = common.getStatSync(UBUNTU_CA_DIR);
  if (stats && stats.isDirectory()) {
    return {
      dir: UBUNTU_CA_DIR,
      cmd: 'update-ca-certificates'
    };
  }
  return {
    dir: FEDORA_CA_DIR,
    cmd: 'update-ca-trust'
  };
}

function installLinux(certFile, execFunc) {
  var config = getCAConfig();
  var certPem = fs.readFileSync(certFile);
  var caFile = config.dir + 'whistle-' + common.createHash(certPem) + '.crt';
  certFile = '"' + certFile.replace(/"/g, '\\"') + '"';
  if (typeof execFunc === 'function') {
    execFunc('cp ' + certFile + ' ' + caFile + '&&' + config.cmd);
  } else {
    execSync('sudo cp ' + certFile + ' ' + caFile + '&&sudo ' + config.cmd);
  }
  return true;
}

module.exports = function(certFile, execFunc) {
  var platform = process.platform;
  if (platform === 'darwin') {
    return installMac(certFile);
  }
  if (platform === 'win32') {
    return installWin(certFile);
  }
  if (platform === 'linux') {
    return installLinux(certFile, execFunc);
  }
  throw new Error('Platform ' + platform + ' is currently unsupported for Root CA installation');
};


================================================
FILE: bin/import.js
================================================
var fs = require('fs');

function importModle(filepath, callback) {
  return import(filepath).then(callback);
}

module.exports = function(filepath, callback) {
  try {
    return callback(require(filepath));
  } catch (e) {
    var code =e && e.code;
    if (code === 'ERR_REQUIRE_ESM') {
      // ignore eslint & fix type=module
      return importModle(filepath, callback);
    } else if (code === 'MODULE_NOT_FOUND' && /\.js$/i.test(filepath)) {
      filepath = filepath.slice(0, -3) + '.mjs';
      if (fs.existsSync(filepath)) {
        return importModle(filepath, callback);
      }
    }
    throw e;
  }
};


================================================
FILE: bin/plugin.d.ts
================================================

export function getWhistlePath(): string;

export function install(cmd: string, argv: string[]): void;

export function uninstall(argv: string[]): void;

export function formatCmdOptions(options: any): any;


================================================
FILE: bin/plugin.js
================================================
var cp = require('child_process');
var fs = require('fs');
var path = require('path');
var fse = require('fs-extra2');
var getHash = require('./util').getHash;
var common = require('../lib/util/common');

var getWhistlePath = common.getWhistlePath;
var WHISTLE_PLUGIN_RE = common.WHISTLE_PLUGIN_RE;
var getPlugins = common.getPlugins;
var CMD_SUFFIX = process.platform === 'win32' ? '.cmd' : '';
var CUSTOM_PLUGIN_PATH = process.env.WHISTLE_CUSTOM_PLUGINS_PATH || path.join(getWhistlePath(), 'custom_plugins');
var DEFAULT_PATH = common.getDefaultWhistlePath();
var REGISTRY_LIST = path.join(DEFAULT_PATH, '.registry.list');
var PACKAGE_JSON = '{"repository":"https://github.com/avwo/whistle","license":"MIT"}';
var LICENSE = 'Copyright (c) 2019 avwo';
var RESP_URL = 'https://github.com/avwo/whistle';
var MAX_REG_COUNT = 100;

function getInstallPath(name, dir) {
  return path.join(dir || CUSTOM_PLUGIN_PATH, name);
}

function removeDirSync(installPath) {
  try {
    fse.removeSync(installPath);
  } catch (e) {}
}

function removeTempFiles(argv) {
  argv.forEach(function(file) {
    if (file.indexOf('file:') === 0) {
      fs.unlink(file.substring(5), common.noop);
    }
  });
}

function renameDirSync(installPath, realPath) {
  fse.ensureDirSync(realPath);
  fse.copySync(installPath, realPath);
  removeDirSync(installPath);
}

function getTempName(name) {
  if (name.indexOf('/') === -1) {
    return '.' + name;
  }
  name = name.split('/');
  var lastIndex = name.length - 1;
  name[lastIndex] = '.' + name[lastIndex];
  return name.join('/');
}

function formatCmdOptions(options) {
  if (CMD_SUFFIX) {
    options.shell = true;
    options.windowsHide = true;
  }
  return options;
}

exports.formatCmdOptions = formatCmdOptions;

function getValue(str) {
  if (str[0] !== '"') {
    return str;
  }
  var len = str.length - 1;
  return str[len] === '"' ? str.substring(1, len) : str;
}

function parseDir(dir) {
  if (!dir) {
    return;
  }
  dir = getValue(dir);
  if (/^~(~)?(?:$|[\/])/.test(dir)) {
    var wave = RegExp.$1;
    var all = RegExp['$&'];
    return path.resolve(wave ? getWhistlePath() : common.getHomedir(), dir.substring(all.length));
  }
  if (common.isWhistleName(dir)) {
    return path.resolve(getWhistlePath(), 'all_whistles/' + dir + '/custom_plugins');
  }
  return path.resolve(dir);
}

function getInstallDir(argv) {
  argv = argv.slice();
  var result = { argv: argv };
  for (var i = 0, len = argv.length; i < len; i++) {
    var option = argv[i];
    if (option === '--dir') {
      result.dir = parseDir(argv[i + 1]);
      argv.splice(i, 2);
      return result;
    }
    if (option && option.indexOf('--dir=') === 0) {
      var dir = option.substring(option.indexOf('=') + 1);
      result.dir = parseDir(dir);
      argv.splice(i, 1);
      return result;
    }
  }
  return result;
}

function getPluginNameFormDeps(deps) {
  var keys = Object.keys(deps);
  for (var i = 0, len = keys.length; i < len; i++) {
    if (WHISTLE_PLUGIN_RE.test(keys[i])) {
      return RegExp.$1;
    }
  }
}

function getPkgName(name) {
  if (/[/\\](whistle\.[a-z\d_-]+)(?:\.git)?$/.test(name)) {
    return RegExp.$1;
  }
  return getHash(name);
}

function install(cmd, name, argv, ver, pluginsCache, callback, handleError) {
  var result = getInstallDir(argv.slice());
  var isPkg = WHISTLE_PLUGIN_RE.test(name);
  var pkgName = isPkg ? name : getPkgName(name);
  var installPath = getInstallPath(getTempName(pkgName), result.dir);
  argv = result.argv;
  fse.ensureDirSync(installPath);
  fse.emptyDirSync(installPath);
  var pkgJson = PACKAGE_JSON;
  if (ver) {
    pkgJson = pkgJson.replace(',', ',"dependencies":{"' + name + '":"' + ver + '"},');
  }
  fs.writeFileSync(path.join(installPath, 'package.json'), pkgJson);
  fs.writeFileSync(path.join(installPath, 'LICENSE'), LICENSE);
  fs.writeFileSync(path.join(installPath, 'README.md'), RESP_URL);
  argv.unshift('install', name);
  pluginsCache[pkgName] = 1;
  var done;
  var child = cp.spawn(cmd, argv, formatCmdOptions({
    stdio: 'inherit',
    cwd: installPath
  }));
  child.once('exit', function(code) {
    !done && handleError && removeTempFiles(argv);
    if (code) {
      if (done) {
        return;
      }
      done = true;
      removeDirSync(installPath);
      callback();
      handleError && handleError('Install plugin \'' + name + '\' failed with code: ' + code);
    } else {
      done = true;
      if (!isPkg) {
        var deps = common.readJsonSync(path.join(installPath, 'package.json'));
        deps = deps && deps.dependencies;
        name = deps && getPluginNameFormDeps(deps);
      }
      if (!name) {
        removeDirSync(installPath);
        return callback();
      }
      var realPath = getInstallPath(name, result.dir);
      removeDirSync(realPath);
      try {
        fs.renameSync(installPath, realPath);
      } catch (e) {
        if (handleError) {
          try {
            renameDirSync(installPath, realPath);
          } catch (e) {
            handleError(e);
          }
        } else {
          renameDirSync(installPath, realPath);
        }
      }
      var pkgPath = path.join(realPath, 'node_modules', name, 'package.json');
      var stats = common.getStatSync(pkgPath);
      if (stats && stats.mtime.getFullYear() < 2010) {
        var now = new Date();
        try {
          fs.utimesSync(pkgPath, now, now);
        } catch (e) {}
      }
      callback(pkgPath);
    }
  });
  if (handleError) {
    child.on('error', function(err) {
      if (done) {
        return;
      }
      done = true;
      handleError(err);
      removeTempFiles(argv);
      removeDirSync(installPath);
      callback();
    });
  }
}

function getRegistry(argv) {
  for (var i = 0, len = argv.length; i < len; i++) {
    var name = argv[i];
    if (name === '--registry') {
      return common.getRegistry(argv[i + 1]);
    }
    if (/^--registry=(.+)/.test(name)) {
      return common.getRegistry(RegExp.$1);
    }
  }
}

function installPlugins(cmd, plugins, argv, pluginsCache, deep, handleError) {
  deep = deep || 0;
  var count = 0;
  var peerPlugins = [];
  var registry = getRegistry(argv);
  var callback = function(pkgPath) {
    if (pkgPath) {
      var pkg = common.readJsonSync(pkgPath) || {};
      var list = pkg.whistleConfig && (pkg.whistleConfig.peerPluginList || pkg.whistleConfig.peerPlugins);
      if (Array.isArray(list) && list.length < 16) {
        list.forEach(function(name) {
          name = typeof name === 'string' ? name.trim() : null;
          if (WHISTLE_PLUGIN_RE.test(name)) {
            name = RegExp.$1;
            if (peerPlugins.indexOf(name) === -1) {
              peerPlugins.push(name);
            }
          }
        });
      }
      if (registry) {
        try {
          fse.ensureDirSync(DEFAULT_PATH);
        } catch (e) {}
        var regList = common.readJsonSync(REGISTRY_LIST);
        var result = [registry];
        registry = null;
        if (Array.isArray(regList)) {
          regList.forEach(function(url) {
            url = common.getRegistry(url);
            if (url && result.indexOf(url) === -1) {
              result.push(url);
            }
          });
        }
        try {
          if (REGISTRY_LIST.length > MAX_REG_COUNT) {
            REGISTRY_LIST = REGISTRY_LIST.slice(0, MAX_REG_COUNT);
          }
          fse.writeJsonSync(REGISTRY_LIST, result);
        } catch (e) {
          try {
            fse.writeJsonSync(REGISTRY_LIST, result);
          } catch (e) {}
        }
      }
    }
    if (--count <= 0 && deep < 16) {
      peerPlugins = peerPlugins.filter(function(name) {
        return !pluginsCache[name];
      });
      peerPlugins.length && installPlugins(cmd, peerPlugins, argv, pluginsCache, ++deep, handleError);
    }
  };
  plugins.forEach(function(name) {
    var ver;
    if (WHISTLE_PLUGIN_RE.test(name)) {
      name = RegExp.$1;
      ver = RegExp.$2;
    } else if (!common.isPluginAddr(name)) {
      return;
    }
    ++count;
    install(cmd, name, argv, ver, pluginsCache, callback, handleError);
  });
}

exports.getWhistlePath = getWhistlePath;

exports.install = function(cmd, argv, handleError) {
  var restArgv = [];
  var plugins = getPlugins(argv, true, restArgv);
  if (!plugins.length) {
    return;
  }
  cmd += CMD_SUFFIX;
  restArgv.push('--no-package-lock');
  installPlugins(cmd, plugins, restArgv, {}, 0, handleError);
};

exports.uninstall = function(plugins) {
  var result = getInstallDir(plugins);
  plugins = result.argv;
  getPlugins(plugins).forEach(function(name) {
    if (WHISTLE_PLUGIN_RE.test(name)) {
      name = RegExp.$1;
      removeDirSync(getInstallPath(name, result.dir));
    }
  });
};

exports.run = function(cmd, argv) {
  var newPath = [];
  fse.ensureDirSync(CUSTOM_PLUGIN_PATH);
  fs.readdirSync(CUSTOM_PLUGIN_PATH).forEach(function(name) {
    if (!name.indexOf('whistle.')) {
      newPath.push(path.join(CUSTOM_PLUGIN_PATH, name, 'node_modules/.bin'));
    } else if (name[0] === '@') {
      try {
        fs.readdirSync(path.join(CUSTOM_PLUGIN_PATH, name)).forEach(function(modName) {
          newPath.push(path.join(CUSTOM_PLUGIN_PATH, name, modName, 'node_modules/.bin'));
        });
      } catch (e) {}
    }
  });
  process.env.PATH && newPath.push(process.env.PATH);
  newPath = newPath.join(CMD_SUFFIX ? ';' : ':');
  process.env.PATH = newPath;
  cp.spawn(cmd + CMD_SUFFIX, argv, formatCmdOptions({
    stdio: 'inherit',
    env: process.env
  }));
};


================================================
FILE: bin/proxy.js
================================================
var net = require('net');
var proxy = require('set-global-proxy');
var util = require('./util');

var OFF_RE = /^(?:o|0|-{0,2}off)$/i;
var BYPASS_RE = /^(?:-{0,2}bypass|-x|-b)$/i;
var NUM_RE = /^\d+$/;
var HOST_SUFFIX_RE = /\:(\d+|auto)?$/;
var HOST_RE = /^[a-z\d_-]+(?:\.[a-z\d_-]+)*$/i;

function showInfo(msg) {
  process.nextTick(function() {
    util.info(msg);
  });
}

function showError(msg) {
  process.nextTick(function() {
    util.error(msg);
  });
}

function enableProxy(options) {
  try {
    var host = util.joinIpPort(options.host, options.port);
    if (proxy.enableProxy(options)) {
      showInfo('Successfully set system proxy (' + host + ')');
    } else {
      showError('Failed to set system proxy (' + host + ')');
    }
  } catch (e) {
    showError(e.message);
  }
}

function disableProxy(sudo) {
  try {
    if (proxy.disableProxy(sudo)) {
      showInfo('Successfully disabled system proxy');
    } else {
      showError('Failed to disable system proxy');
    }
  } catch (e) {
    showError(e.message);
  }
}

module.exports = function(argv) {
  var cmd = argv[0];
  var sudo = argv.indexOf('--no-sudo') === -1;
  if (OFF_RE.test(cmd)) {
    return disableProxy(sudo);
  }
  var options = {};
  var skip;
  argv.forEach(function(arg) {
    if (skip) {
      options.bypass = arg;
      skip = false;
    } else if (BYPASS_RE.test(arg)) {
      skip = true;
    } else if (NUM_RE.test(arg)) {
      options.port = parseInt(arg, 10) || options.port;
    } else if (net.isIP(arg)) {
      options.host = arg || options.host;
    } else if (HOST_SUFFIX_RE.test(arg)) {
      var port = RegExp.$1;
      delete options.port;
      if (port > 0) {
        options.port = parseInt(port, 10) || options.port;
      }
      var host = arg.slice(0, - port.length - 1);
      if (host[0] === '[') {
        host = host.substring(1);
      }
      var lastIndex = host.length - 1;
      if (host[lastIndex] === ']') {
        host = host.substring(0, lastIndex);
      }
      if (host && (net.isIP(host) || HOST_RE.test(host))) {
        options.host = host || options.host;
      }
    }
  });
  if (!options.port) {
    options.port = util.getDefaultPort();
  }
  options.host = options.host || '127.0.0.1';
  options.sudo = sudo;
  enableProxy(options);
};


================================================
FILE: bin/status.js
================================================
var util = require('./util');
var pkg = require('../package.json');
var colors = require('colors/safe');
var isRunning = util.isRunning;
var showUsage = util.showUsage;
var readConfig = util.readConfig;
var readConfigList = util.readConfigList;
var warn = util.warn;
var info = util.info;

function showAll(byStop) {
  var list = readConfigList().map(function(config) {
    return new Promise(function(resolve) {
      isRunning(config.pid, function(running) {
        resolve(running && config);
      });
    });
  });
  Promise.all(list).then(function(confList) {
    confList = confList.filter(function(conf) {
      return conf;
    });
    var len = confList.length;
    if (!len) {
      warn('[!] No running Whistle instances');
    } else {
      var tips = ['[i] All running Whistle instances:'];
      confList.forEach(function(conf, i) {
        ++i;
        var options = conf.options;
        tips.push('  ' + i + '.' + (conf.pid ? ' PID: ' + conf.pid + ',' : '')
          + ' Port: ' + (options.port || pkg.port)
          + (options.host ? ', Host: ' + options.host : '')
          + (options.storage ? ', Storage: ' + options.storage : '')
          + (byStop ? colors.red(' (Stop cmd: ' + (options.storage ? 'w2 stop -S ' + options.storage : 'w2 stop') + ')') : ''));
      });
      byStop && warn('[!] This Whistle instance is not running');
      info(tips.join('\n'));
    }
  });

  // All running whistle:
  // 1. port: 8899
  // 2. port: 888, storage: xxx
}

module.exports = function(all, storage) {
  if (!all) {
    var config = readConfig(storage) || '';
    var pid = config.pid;
    var options = pid && config.options;
    if (pid) {
      isRunning(pid, function(running) {
        if (running) {
          return showUsage(true, options);
        }
        showAll();
      });
      return;
    }
  }
  showAll();
};

module.exports.showAll = showAll;


================================================
FILE: bin/use.js
================================================
var path = require('path');
var http = require('http');
var url = require('url');
var util = require('./util');
var importModule = require('./import');
var pkg = require('../package.json');
var common = require('../lib/util/common');

var isRunning = util.isRunning;
var error = util.error;
var warn = util.warn;
var info = util.info;
var readConfig = util.readConfig;
var MAX_RULES_LEN = 1024 * 256;
var DEFAULT_OPTIONS = util.DEFAULT_OPTIONS;
var options;

function showStartWhistleTips(storage, isClient) {
  if (isClient) {
    error('No running Whistle client. Please install and start the latest Whistle client: https://github.com/avwo/whistle-client');
  } else {
    error('No running Whistle instances. Execute `w2 start' + (storage ? ' -S ' + storage : '') + '` to start Whistle on the cli');
  }
}

function handleRules(filepath, callback, port) {
  importModule(filepath, function(getRules) {
    if (typeof getRules !== 'function') {
      return callback(getRules);
    }
    var opts = {
      port: port,
      existsPlugin: existsPlugin
    };
    if (options && options.host) {
      opts.host = options.host;
    }
    getRules(callback, opts);
  });
}

function getString(str) {
  return typeof str !== 'string' ? '' : str.trim();
}

function existsPlugin(name) {
  if (!name || typeof name !== 'string') {
    return false;
  }
  var pluginPaths = require('../lib/plugins/module-paths').getPaths();
  for (var i = 0, len = pluginPaths.length; i < len; i++) {
    var stats = common.getStatSync(path.join(pluginPaths[i], name));
    if (stats && stats.isDirectory()) {
      return true;
    }
  }
  return false;
}

var reqOptions;
function request(body, callback) {
  if (!reqOptions) {
    reqOptions = url.parse('http://' + util.joinIpPort(options.host || '127.0.0.1', options.port) + '/cgi-bin/rules/project');
    reqOptions.headers = {
      'content-type': 'application/x-www-form-urlencoded'
    };
    if (options.specialAuth) {
      reqOptions.headers['x-whistle-special-auth'] = options.specialAuth;
    }
    reqOptions.method = 'POST';
    if (options.username || options.password) {
      var auth = [options.username || '', options.password || ''].join(':');
      reqOptions.headers.authorization = 'Basic ' + new Buffer.from(auth).toString('base64');
    }
  }
  var req = http.request(reqOptions, function(res) {
    util.getBody(res, function(err, data) {
      if (err) {
        throw err;
      }
      callback(data);
    });
  });
  // 不处理错误,直接抛出终止进程
  req.end(body);
}

function checkDefault(running, storage, isClient, callback) {
  if (running) {
    return callback();
  }
  if (isClient) {
    return callback(true);
  }
  var execCallback = function(err) {
    callback && callback(err);
    callback = null;
  };
  var req = http.get('http://' + DEFAULT_OPTIONS.host + ':' + DEFAULT_OPTIONS.port + '/cgi-bin/status', function(res) {
    res.on('error', execCallback);
    util.getBody(res, function(err, data) {
      if (err || !data || data.name !== pkg.name || data.storage !== storage) {
        return execCallback(true);
      }
      callback(null, DEFAULT_OPTIONS.port);
    });
  });
  req.on('error', execCallback);
  req.end();
}

function readClientConfig() {
  var procPath = path.join(common.getHomedir(), '.whistle_client.pid');
  var info = (common.readFileTextSync(procPath) || '').split(',');
  if (info && info.length === 4) {
    return {
      pid: info[0],
      options: {
        host: info[1],
        port: info[2],
        specialAuth: info[3]
      }
    };
  }
}

module.exports = function(filepath, storage, force, isClient) {
  var config;
  var dir = '';
  if (isClient) {
    storage = '';
    config = readClientConfig() || '';
  } else {
    storage = storage || '';
    dir = encodeURIComponent(storage);
    config = readConfig(dir) || '';
    if (config.options) {
      delete config.options.specialAuth;
    }
  }
  options = config.options || '';
  isRunning(options && config.pid, function(running) {
    checkDefault(running, dir, isClient, function(err, port) {
      if (err) {
        return showStartWhistleTips(storage, isClient);
      }
      filepath = path.resolve(filepath || '.whistle.js');
      if (port) {
        options = DEFAULT_OPTIONS;
      } else {
        port = options.port = options.port > 0 ? options.port : pkg.port;
      }
      handleRules(filepath, function(result) {
        if (!result) {
          error('The name and rules are required');
          return;
        }
        var name = getString(result.name);
        if (!name || name.length > 64) {
          error('The name must be 1-64 characters');
          return;
        }
        var rules = getString(result.rules);
        if (rules.length > MAX_RULES_LEN) {
          error('Maximum rules size: 256KB');
          return;
        }
        var groupName = getString(result.groupName) || getString(result.group);
        var setRules = function() {
          var body = [
            'name=' + encodeURIComponent(name),
            'rules=' + encodeURIComponent(rules),
            'groupName=' + encodeURIComponent(groupName.trim())
          ].join('&');
          request(body, function() {
            info('Successfully configured rules for Whistle' + (isClient ? ' client' : '') + ' (' + util.joinIpPort(options.host || '127.0.0.1', port) + ')');
          });
        };
        if (force) {
          return setRules();
        }
        request('name=' + encodeURIComponent(name) + '&enable=1&top=1', function(data) {
          if (data.rules) {
            info('Successfully enabled');
            warn('Warning: Rule already exists. Use \'--force\' to override');
            return;
          }
          setRules();
        });
      }, port);
    });
  });
};


================================================
FILE: bin/util.js
================================================
var cp = require('child_process');
var program = require('starting');
var util = require('util');
var os = require('os');
var fs = require('fs');
var config = require('../lib/config');
var common = require('../lib/util/common');
var colors = require('colors/safe');
var path = require('path');
var extend = require('extend');
var createHmac = require('crypto').createHmac;

var joinIpPort = common.joinIpPort;
var DEFAULT_OPTIONS = { host: '127.0.0.1', port: 8899 };

exports.joinIpPort = joinIpPort;
exports.DEFAULT_OPTIONS = DEFAULT_OPTIONS;
/*eslint no-console: "off"*/
var CHECK_RUNNING_CMD = process.platform === 'win32' ?
  'tasklist /fi "PID eq %s" | findstr /i "node.exe"'
  : 'ps -f -p %s | grep "node"';
var isWin = process.platform === 'win32';

function isRunning(pid, callback) {
  pid ? cp.exec(util.format(CHECK_RUNNING_CMD, pid),
    function (err, stdout, stderr) {
      callback(!err && !!stdout.toString().trim());
    }) : callback();
}

exports.isRunning = isRunning;


function getIpList() {
  var ipList = [];
  var ifaces = os.networkInterfaces();
  Object.keys(ifaces).forEach(function(ifname) {
    ifaces[ifname].forEach(function (iface) {
      if (iface.family == 'IPv4' || iface.family === 4) {
        ipList.push(iface.address);
      }
    });
  });
  var index = ipList.indexOf('127.0.0.1');
  if (index !== -1) {
    ipList.splice(index, 1);
  }
  ipList.unshift('127.0.0.1');
  return ipList;
}

function error(msg) {
  console.log(colors.red(msg));
}

function warn(msg) {
  console.log(colors.yellow(msg));
}

function info(msg) {
  console.log(colors.green(msg));
}
exports.error = error;
exports.warn = warn;
exports.info = info;

function showKillError() {
  error('[!] Cannot kill ' + config.appName + ' owned by root');
  info('[i] Try to run command ' + (isWin ? 'as an administrator' : 'with sudo'));
}

exports.showKillError = showKillError;

function showUsage(isRunning, options, restart) {
  var rcConf;
  if (isRunning) {
    if (restart) {
      showKillError();
    } else {
      warn('[!] ' + config.appName + '@' + config.version + ' is running');
    }
  } else {
    rcConf = common.readWhistleRc(options);
    if (rcConf) {
      var rcStr = JSON.stringify(rcConf);
      if (rcStr.length > 30) {
        rcStr = rcStr.substring(0, 27) + '...';
      }
      info('[i] Load configuration from ~/.whistlerc: ' + rcStr);
    }
    info('[i] ' + config.appName + '@' + config.version + (restart ? ' restarted' : ' started'));
  }
  options = options ? extend({}, rcConf, options) : rcConf;
  options = formatOptions(options);
  var port = /^\d+$/.test(options.port) && options.port > 0 ?  options.port : config.port;
  var list = common.isString(options.host) ? [options.host] : getIpList();
  var oneIp = list.length === 1;
  var index = 0;
  if (!oneIp) {
    info('[i] ' + (++index) + '. Use your device to visit these URLs and note which one works:');
    info(list.map(function(ip) {
      return '       http://' + colors.bold(joinIpPort(ip, port != 80 && port)) + '/';
    }).join('\n'));
    warn('       Note: If none are accessible, check your firewall settings');
    warn('             For help, see ' + colors.bold('https://github.com/avwo/whistle'));
  }
  info('[i] ' + (++index) + '. Set your device\'s HTTP PROXY to ' + colors.bold((oneIp ? 'IP(' + list[0] + ')' : 'the working IP') + ' & PORT(' + port + ')'));
  info('[i] ' + (++index) + '. Open ' + colors.bold('Chrome') + ' and visit ' + colors.bold('http://' + (options.localUIHost || config.localUIHost) + '/') + ' to begin');

  var bypass = program.init;
  if (bypass == null) {
    return;
  }
  return {
    host: options.host || '127.0.0.1',
    port: port,
    bypass: typeof bypass === 'string' ? bypass : undefined
  };
}

exports.showUsage = showUsage;

function getDataDir() {
  return path.resolve(common.getHomedir(), '.startingAppData');
}

function formatOptions(options) {
  if (!options || (!/^(?:([\w.-]+):)?([1-9]\d{0,4})$/.test(options.port) &&
    !/^\[([\w.:]+)\]:([1-9]\d{0,4})$/.test(options.port))) {
    return options;
  }
  options.host = options.host || RegExp.$1;
  options.port = parseInt(RegExp.$2, 10);
  return options;
}

exports.formatOptions = formatOptions;

function readConfig(storage) {
  var dataDir = getDataDir();
  var configFile = path.join(dataDir, encodeURIComponent('#' + (storage ? storage + '#' : '')));
  var conf = common.readJsonSync(configFile);
  conf && formatOptions(conf.options);
  return conf;
}

function readConfigList() {
  var dataDir = getDataDir();
  var result = [];
  try {
    fs.readdirSync(dataDir).forEach(function(dir) {
      try {
        dir = decodeURIComponent(dir);
        var lastIndex = dir.length - 1;
        if (dir[0] === '#' && dir[lastIndex] === '#') {
          dir = dir.substring(1, lastIndex || 1);
          var config = readConfig(dir);
          if (config && config.pid && config.options) {
            result.push(config);
          }
        }
      } catch(e) {}
    });
  } catch(e) {}
  return result;
}

exports.readConfig = readConfig;
exports.readConfigList = readConfigList;
exports.getHash = function(str) {
  var hmac = createHmac('sha256', '5b6af7b9884e1165');
  return hmac.update(str).digest('hex');
};

exports.getDefaultPort = function () {
  var conf = readConfig();
  conf = conf && conf.options;
  var port = conf && conf.port;
  return port > 0 ? port : 8899;
};

function getBody(res, callback) {
  var resBody;
  res.on('data', function(data) {
    resBody = resBody ? Buffer.concat([resBody, data]) : data;
  });
  res.on('end', function() {
    if (res.statusCode != 200) {
      callback(resBody || 'response ' + res.statusCode + ' error');
    } else {
      callback(null, JSON.parse(resBody + ''));
    }
  });
}

exports.getBody = getBody;


================================================
FILE: bin/whistle.js
================================================
#! /usr/bin/env node
/*eslint no-console: "off"*/
var program = require('starting');
var path = require('path');
var http = require('http');
var config = require('../lib/config');
var useRules = require('./use');
var showStatus = require('./status');
var util = require('./util');
var plugin = require('./plugin');
var setProxy = require('./proxy');
var installCA = require('./ca/cli');
var colors = require('colors');

var error = util.error;
var info = util.info;
var OPTIONS = util.DEFAULT_OPTIONS;

function getLatestVersion(options, cb, index) {
  var done;
  var handleCb = function(err, data) {
    if (done) {
      return;
    }
    index = index || 0;
    if (index < 5 && (err || !data)) {
      return setTimeout(function() {
        getLatestVersion(options, cb, index + 1);
      }, 300);
    }
    done = true;
    cb(data && data.hasNewVersion ? data.latestVersion : '');
  };
  options = options || OPTIONS;
  var req = http.get('http://' + util.joinIpPort(options.host || OPTIONS.host, options.port || OPTIONS.port) + '/cgi-bin/check-update', function(res) {
    res.on('error', handleCb);
    util.getBody(res, handleCb);
  });
  req.on('error', handleCb);
  req.end();
}

function handleEnd(err, options, restart, run) {
  var result = util.showUsage(err, options, restart);
  getLatestVersion(options, function(latestVersion) {
    if (latestVersion) {
      error('[!] A new version is available (v' + latestVersion + '). Run \'' + colors.bold('npm i -g ' + config.name) + '\' to update');
    }
    run && console.log('Press [Ctrl+C] to stop ' + config.appName + '...');
  });
  if (!result) {
    return;
  }
  var host = util.joinIpPort(result.host, result.port);
  var argv = [host];
  if (result.bypass) {
    argv.push('-x', result.bypass);
  }
  setProxy(argv);
  installCA([host]);
}

function showStartupInfo(err, options, debugMode, restart) {
  if (!err || err === true) {
    return handleEnd(err, options, restart);
  }
  if (/listen EADDRINUSE/.test(err)) {
    options = util.formatOptions(options);
    var port = options.port || config.port;
    error('[!] Failed to bind proxy port ' + (options.host ? util.joinIpPort(options.host, port) : port) + ': Port already in use');
    info('[i] ' + config.appName + ' may already be running. Try: ' + (debugMode ? 'w2 stop' : 'w2 restart') + ' to ' + (debugMode ? 'stop' : 'restart') + ' ' + config.appName);
    info('    or use a different port with: ' + (debugMode ? '`w2 run -p newPort`\n' : '`w2 start -p newPort`\n'));
  } else if (err.code == 'EACCES' || err.code == 'EPERM') {
    error('[!] Permission denied: Cannot start ' + config.appName + ' as root');
    info('[i] Try running with sudo\n');
  }

  error(err.stack ? 'Date: ' + new Date().toLocaleString() + '\n' + err.stack : err);
}

function getName() {
  if (/[/\\](\w+)$/.test(process.argv[1])) {
    return RegExp.$1;
  }
}

program.setConfig({
  main: function(options) {
    var cmd = process.argv[2];
    if ((cmd === 'start' || cmd === 'restart') && (options.inspect || options.inspectBrk)) {
      error('[!] Inspector mode only supported with `w2 run` command');
      var argv = Array.prototype.slice.call(process.argv, 3);
      info('[i] Usage: w2 run' + (argv.length ? ' ' + argv.join(' ') : ''));
      return process.exit(1);
    }
    var hash = options && options.storage && encodeURIComponent(options.storage);
    return path.join(__dirname, '../index.js') + (hash ? '#' + hash + '#' : '');
  },
  name: getName() || config.name,
  version: config.version,
  runCallback: function(err, options) {
    if (err) {
      showStartupInfo(err, options, true);
      return;
    }
    handleEnd(false, options, false, true);
  },
  startCallback: showStartupInfo,
  restartCallback: function(err, options) {
    showStartupInfo(err, options, false, true);
  },
  stopCallback: function(err) {
    if (err === true) {
      info('[i] ' + config.appName + ' killed');
    } else if (err) {
      if (err.code === 'EPERM') {
        util.showKillError();
      } else {
        error('[!] ' + err.message);
      }
    } else {
      showStatus.showAll(true);
    }
  }
});

program
  .command('status')
  .description('Display running status');
program
  .command('add')
  .description('Add rules from local JS file (.whistle.js by default)');
program.command('proxy')
  .description('Configure system proxy settings');
program.command('ca')
  .description('Manage Root CA certificates');
program.command('install')
  .description('Install Whistle plugin');
program.command('uninstall')
  .description('Uninstall Whistle plugin');
program.command('exec')
  .description('Execute plugin command');

program
  .option('-D, --baseDir [baseDir]', 'set storage root path', String, undefined)
  .option('-z, --certDir [directory]', 'set custom certificate directory', String, undefined)
  .option('-l, --localUIHost [hostname]', 'set web UI domain (' + config.localUIHost + ' by default)', String, undefined)
  .option('-L, --pluginHost [hostname]', 'set plugin UI domains  (as: "script=a.b.com&vase=x.y.com")', String, undefined)
  .option('-n, --username [username]', 'set web UI username', String, undefined)
  .option('-w, --password [password]', 'set web UI password', String, undefined)
  .option('-N, --guestName [username]', 'set web UI guest username (read-only)', String, undefined)
  .option('-W, --guestPassword [password]', 'set web UI guest password (read-only)', String, undefined)
  .option('-s, --sockets [number]', 'set max cached connections per domain (' + config.sockets + ' by default)', parseInt, undefined)
  .option('-S, --storage [newStorageDir]', 'set configuration storage directory', String, undefined)
  .option('-C, --copy [storageDir]', 'copy configuration from specified directory', String, undefined)
  .option('-c, --dnsCache [time]', 'set DNS cache time (default: 60000ms)', String, undefined)
  .option('-H, --host [boundHost]', 'set bound host (default: INADDR_ANY)', String, undefined)
  .option('-p, --port [proxyPort]', 'set proxy port (default: ' + config.port + ' by default)', String, undefined)
  .option('-P, --uiport [uiport]', 'set web UI port', String, undefined)
  .option('-m, --middlewares [script path or module name]', 'set startup middlewares (format: xx,yy/zz.js)', String, undefined)
  .option('-M, --mode [mode]', 'set startup mode (options: pureProxy|debug|multiEnv|capture|disableH2|network|rules|plugins|prod)', String, undefined)
  .option('-t, --timeout [ms]', 'set request timeout (default: ' + config.timeout, parseInt, undefined)
  .option('-e, --extra [extraData]', 'set plugin extra parameters', String, undefined)
  .option('-f, --secureFilter [secureFilter]', 'set secure filter path', String, undefined)
  .option('-r, --shadowRules [shadowRules]', 'set default shadow rules', String, undefined)
  .option('-R, --reqCacheSize [reqCacheSize]', 'set request data cache size (default: 600)', String, undefined)
  .option('-F, --frameCacheSize [frameCacheSize]', 'set WebSocket frame cache size (default: 512)', String, undefined)
  .option('-A, --addon [pluginPaths]', 'add custom plugin paths', String, undefined)
  .option('--init [bypass]', 'auto configure proxy and install Root CA')
  .option('--cluster [workers]', 'start cluster with worker count (default: CPU cores)', String, undefined)
  .option('--config [config]', 'load startup config from file', String, undefined)
  .option('--rcPath [rcPath]', 'load configuration from file (default: ~/.whistlerc)', String, undefined)
  .option('--dnsServer [dnsServer]', 'set custom DNS servers', String, undefined)
  .option('--socksPort [socksPort]', 'set SOCKSv5 server port', String, undefined)
  .option('--httpPort [httpPort]', 'set HTTP server port', String, undefined)
  .option('--httpsPort [httpsPort]', 'set HTTPS server port', String, undefined)
  .option('--allowOrigin [originList]', 'set allowed CORS origins (format: a.b.c,x.y.z or *)', String, undefined)
  .option('--no-global-plugins', 'disable global plugins')
  .option('--no-prev-options', 'ignore previous options on restart')
  .option('--inspect [[host:]port]', 'enable inspector (default: 127.0.0.1:9229)')
  .option('--inspectBrk [[host:]port]', 'enable inspector with breakpoint (default: 127.0.0.1:9229)');

var argv = process.argv;
var cmd = argv[2];
var storage;
var removeItem = function(list, name) {
  var i = list.indexOf(name);
  i !== -1 && list.splice(i, 1);
};
if (argv.indexOf('--init') !== -1) {
  process.env.WHISTLE_MODE = (process.env.WHISTLE_MODE || '') + '|persistentCapture';
}
if (cmd === 'status') {
  var all = argv[3] === '--all' || argv[3] === '-l';
  if (argv[3] === '-S') {
    storage = argv[4];
  }
  showStatus(all, storage);
} else if (cmd === 'proxy') {
  setProxy(Array.prototype.slice.call(argv, 3));
} else if (cmd === 'ca') {
  installCA(Array.prototype.slice.call(argv, 3));
} else if (/^([a-z]{1,2})?uni(nstall)?$/.test(cmd)) {
  plugin.uninstall(Array.prototype.slice.call(argv, 3));
} else if (/^([a-z]{1,2})?i(nstall)?$/.test(cmd)) {
  cmd = (RegExp.$1 || '') + 'npm';
  argv = Array.prototype.slice.call(argv, 3);
  removeItem(argv, '-g');
  removeItem(argv, '--global');
  plugin.install(cmd, argv);
} else if (cmd === 'use' || cmd === 'enable' || cmd === 'add') {
  var index = argv.indexOf('--force');
  var force = index !== -1;
  if (force) {
    argv.splice(index, 1);
  }
  index = argv.indexOf('-c');
  var isClient = index !== -1;
  if (isClient) {
    argv.splice(index, 1);
  }
  index = argv.indexOf('--client');
  if (index !== -1) {
    isClient = true;
    argv.splice(index, 1);
  }
  var filepath = argv[3];
  if (filepath === '-S') {
    filepath = null;
    storage = argv[4];
  } else if (argv[4] === '-S') {
    storage = argv[5];
  }
  if (filepath && /^-/.test(filepath)) {
    filepath = null;
  }
  useRules(filepath, storage, force, isClient);
} else if ((cmd === 'run' || cmd === 'exec') && argv[3] && /^[^-]/.test(argv[3])) {
  cmd = argv[3];
  argv = Array.prototype.slice.call(argv, 4);
  plugin.run(cmd, argv);
} else {
  var pluginIndex = argv.indexOf('--pluginPaths');
  if (pluginIndex !== -1) {
    argv[pluginIndex] = '--addon';
  }
  program.parse(argv);
}


================================================
FILE: biz/index.js
================================================
var net = require('net');
var rules = require('../lib/rules');
var util = require('../lib/util');
var handleUIReq = require('./webui/lib').handleRequest;
var handleWeinreReq = require('./weinre');
var config = require('../lib/config');
var common = require('../lib/util/common');

var localIpCache = util.localIpCache;
var WEBUI_PATH = config.WEBUI_PATH;
var CUSTOM_WEBUI_PATH = /\/[\w.-]*\.whistle-path\.5b6af7b9884e1165[\w.-]*\/+/;
var CUSTOM_WEBUI_PATH_RE = /^\/[\w.-]*\.whistle-path\.5b6af7b9884e1165[\w.-]*\/+/;
var PREVIEW_PATH_RE = config.PREVIEW_PATH_RE;
var WEBUI_PATH_RE = util.escapeRegExp(WEBUI_PATH, true);
var REAL_WEBUI_HOST = new RegExp('^' + WEBUI_PATH_RE + '(__([a-z\\d.-]+)(?:__(\\d{1,5}))?__/)');
var INTERNAL_APP = new RegExp('^' + WEBUI_PATH_RE + '(log|weinre|cgi)(?:\\.(\\d{1,5}))?/');
var PLUGIN_RE = new RegExp('^' + WEBUI_PATH_RE + 'whistle\\.([a-z\\d_-]+)/');
var CUSTOM_REAL_WEBUI_HOST = new RegExp('^/[\\w.-]*\\.whistle-path\\.5b6af7b9884e1165[\\w.-]*/+(__([a-z\\d.-]+)(?:__(\\d{1,5}))?__/)');
var CUSTOM_INTERNAL_APP = new RegExp('^/[\\w.-]*\\.whistle-path\\.5b6af7b9884e1165[\\w.-]*/+(log|weinre|cgi)(?:\\.(\\d{1,5}))?/');
var CUSTOM_PLUGIN_RE = new RegExp('^/[\\w.-]*\\.whistle-path\\.5b6af7b9884e1165[\\w.-]*/+whistle\\.([a-z\\d_-]+)/');
var REAL_WEBUI_HOST_PARAM = /_whistleInternalHost_=(__([a-z\d.-]+)(?:__(\d{1,5}))?__)/;
var OUTER_PLUGIN_RE = /^(?:\/whistle)?\/((?:whistle|plugin)\.[a-z\\d_-]+)::(\d{1,5})\//;

function transformUI(req, res) {
  if (config.customUIHost && !config.keepProxyUI) {
    return res.status(404).end();
  }
  return handleUIReq(req, res);
}

module.exports = function(req, res, next) {
  var config = this.config;
  var pluginMgr = this.pluginMgr;
  var fullUrl = req.fullUrl = util.getFullUrl(req); // format request
  var headers = req.headers;
  var host = util.parseHost(headers.host);
  var port = host[1] || (req.isHttps ? 443 : 80);
  var bypass;
  host = host[0];
  req._w2hostname = host;
  var transformPort, isProxyReq, isWeinre, isOthers;
  var webUI = WEBUI_PATH;
  var realHostRe = REAL_WEBUI_HOST;
  var internalAppRe = INTERNAL_APP;
  var pluginRe = PLUGIN_RE;
  var isWebUI = req.path.indexOf(WEBUI_PATH) === 0;
  var isOld;
  if (!isWebUI && CUSTOM_WEBUI_PATH_RE.test(req.path)) {
    isWebUI = true;
    isOld = true;
    webUI = CUSTOM_WEBUI_PATH;
    realHostRe = CUSTOM_REAL_WEBUI_HOST;
    internalAppRe = CUSTOM_INTERNAL_APP;
    pluginRe = CUSTOM_PLUGIN_RE;
  }
  if (isWebUI) {
    isWebUI = !config.pureProxy;
    var realHost;
    if (isWebUI) {
      if (realHostRe.test(req.path) || REAL_WEBUI_HOST_PARAM.test(req.url)) {
        var realPath = RegExp.$1;
        var realPort = RegExp.$3;
        realHost = RegExp.$2 + (realPort ? ':' + realPort : '');
        headers[util.REAL_HOST_HEADER] = realHost;
        req.url = req.url.replace(realPath, '');
      } else {
        req.curUrl = fullUrl;
        if (realHost = rules.resolveInternalHost(req)) {
          headers[util.REAL_HOST_HEADER] = realHost;
        }
      }
      if (internalAppRe.test(req.path)) {
        transformPort = RegExp.$2;
        isWeinre = RegExp.$1 === 'weinre';
        if (transformPort) {
          isOthers = isProxyReq = transformPort != config.port;
        } else {
          isProxyReq = false;
          transformPort = config.port;
        }
        isProxyReq = isProxyReq || isOld;
      } else if (pluginRe.test(req.path)) {
        isProxyReq = !pluginMgr.getPlugin(RegExp.$1 + ':');
      } else if (!headers[config.WEBUI_HEAD]) {
        isWebUI = false;
      }
      if (!config.proxyServer && isProxyReq && !config.isLocalUIUrl(host)) {
        isWebUI = false;
        req.isPluginReq = true;
        req._isProxyReq = true;
      }
      if (isWebUI) {
        req.fromInternalPath = true;
        var hostname = (req._fwdHost && util.parseHost(req._fwdHost)[0]) || host;
        headers[common.ORIGIN_HOST_HEADER] = hostname || '*';
      }
    }
  } else {
    isWebUI = headers[config.WEBUI_HEAD];
    if (!isWebUI) {
      if (!(isWebUI = localIpCache.get(host))) {
        isWebUI = config.isLocalUIUrl(host);
        if (isWebUI ? net.isIP(host) : util.isLocalHost(host)) {
          isWebUI = util.isProxyPort(port);
        }
      }
    } else if (util.isProxyPort(port) && net.isIP(host)) {
      localIpCache.set(host, 1);
    }
    if (PREVIEW_PATH_RE.test(req.url)) {
      headers[util.INTERNAL_ID_HEADER] = util.INTERNAL_ID;
      req.url = '/preview.html?charset=' + RegExp.$1;
      isWebUI = true;
    } else if (isWebUI) {
      if (req.path.indexOf('/_/') === 0) {
        bypass = '/_/';
      } else if (req.path.indexOf('/-/') === 0) {
        bypass = '/-/';
      }
      if (bypass) {
        req.url = req.url.replace(bypass, '/');
      }
      delete headers[util.INTERNAL_ID_HEADER];
    }
  }
  // 后续有用到
  fullUrl = req.fullUrl = util.getFullUrl(req);
  if (bypass) {
    return next();
  }
  var localRule;
  req.curUrl = fullUrl;
  if (isWebUI) {
    if (isOthers) {
      util.transformReq(req, res, transformPort);
    } else {
      req.url = req.url.replace(transformPort ? internalAppRe : webUI, '/');
      if (OUTER_PLUGIN_RE.test(req.path)) {
        var outerPort = RegExp.$2;
        req.url = req.url.replace(RegExp['$&'], '/' + RegExp.$1 + '/');
        if (outerPort > 0 && outerPort < 65536 && outerPort != config.port) {
          headers.host = '127.0.0.1:' + outerPort;
          return util.transformReq(req, res, outerPort);
        }
      }
      req._hasRespond = true;
      if (isWeinre) {
        handleWeinreReq(req, res);
      } else {
        transformUI(req, res);
      }
    }
  } else if (localRule = rules.resolveLocalRule(req)) {
    req.url = localRule.url;
    if (localRule.realPort) {
      headers.host = '127.0.0.1:' + localRule.realPort;
      util.transformReq(req, res, localRule.realPort);
    } else {
      transformUI(req, res);
    }
  } else {
    next();
  }
};



================================================
FILE: biz/init.js
================================================
var http = require('http');
var ui = require('./webui/lib');
var util = require('../lib/util');

module.exports = function init(proxy, callback) {
  var config = proxy.config;
  ui.init(proxy);
  if (config.customUIPort) {
    var server = http.createServer();
    ui.setupServer(server);
    util.getBoundIp(config.uihost, function(host) {
      if (host) {
        config.customUIHost = host;
        server.listen(config.uiport, host, callback);
      } else {
        server.listen(config.uiport, callback);
      }
    });
  } else {
    callback();
  }
};


================================================
FILE: biz/webui/cgi-bin/abort.js
================================================
var proxy = require('../lib/proxy');
var socketMgr = proxy.socketMgr;

function abort(reqId) {
  proxy.abortRequest(reqId);
  socketMgr.abort(reqId);
}

module.exports = function(req, res) {
  var list = req.body.list;
  if (list && typeof list === 'string') {
    list.split(',').forEach(abort);
  }
  res.json({ ec: 0 });
};


================================================
FILE: biz/webui/cgi-bin/add-rules-values.js
================================================
var rules = require('../../../lib/rules/util').rules;
var values = require('../../../lib/rules/util').values;

module.exports = function(req, res) {
  var body = req.body;
  var clientId = body.clientId;
  var rulesData = body.rules;
  var valuesData = body.values;
  if (rulesData) {
    if (rulesData.name === 'Default') {
      rules.setDefault(rulesData.value, clientId);
      rules.enableDefault();
    } else {
      rules.add(rulesData.name, rulesData.value, clientId);
      rules.select(rulesData.name);
    }
  }
  if (valuesData) {
    values.add(valuesData.name, valuesData.value, clientId);
  }
  res.json({ec: 0, em: 'success'});
};


================================================
FILE: biz/webui/cgi-bin/certs/active.js
================================================
var ca = require('../../../../lib/https/ca');

module.exports = function(req, res) {
  ca.setActiveCert(req.body);
  res.json(ca.getCustomCertsFiles());
};


================================================
FILE: biz/webui/cgi-bin/certs/all.js
================================================
var ca = require('../../../../lib/https/ca');

module.exports = function(req, res) {
  res.json({
    certs: ca.getCustomCertsFiles(),
    dir: ca.CUSTOM_CERTS_DIR
  });
};


================================================
FILE: biz/webui/cgi-bin/certs/remove.js
================================================
var ca = require('../../../../lib/https/ca');

module.exports = function(req, res) {
  ca.removeCert(req.body);
  var isparsed = req.query.dataType === 'parsed';
  res.json(isparsed ? ca.getCustomCertsInfo() : ca.getCustomCertsFiles());
};


================================================
FILE: biz/webui/cgi-bin/certs/upload.js
================================================
var ca = require('../../../../lib/https/ca');

module.exports = function(req, res) {
  ca.uploadCerts(req.body);
  var isparsed = req.query.dataType === 'parsed';
  res.json(isparsed ? ca.getCustomCertsInfo() : ca.getCustomCertsFiles());
};


================================================
FILE: biz/webui/cgi-bin/check-update.js
================================================
var properties = require('../../../lib/rules/util').properties;
var config = require('../../../lib/config');
var common = require('../../../lib/util/common');

module.exports = function(req, res) {
  var version = config.version;
  var doNotShowAgainVersion = properties.get('doNotShowAgainVersion');
  var latestVersion = properties.getLatestVersion('latestVersion');
  var latestClientVersion = properties.getLatestVersion('latestClientVersion');
  var hasNewVersion = common.compareVersion(latestVersion, version);

  res.json({
    ec: 0,
    em: 'success',
    showUpdate: !config.disableUpdateTips && hasNewVersion > 1 && common.compareVersion(latestVersion, doNotShowAgainVersion) > 1,
    hasNewVersion: hasNewVersion > 0,
    hasUpdater: config.hasUpdater,
    version: config.version,
    latestVersion: latestVersion,
    latestClientVersion: latestClientVersion
  });
};



================================================
FILE: biz/webui/cgi-bin/cookies.js
================================================
var sendGzip = require('./util').sendGzip;
var proxy = require('../lib/proxy');

module.exports = function(req, res) {
  sendGzip(req, res, {
    ec: 0,
    cookies: proxy.getCookiesByDomain(req.query.domain)
  });
};


================================================
FILE: biz/webui/cgi-bin/create-cert.js
================================================
var Zip = require('adm-zip');
var qs = require('querystring');
var ca = require('../../../lib/https/ca');
var sendError = require('./util').sendError;

var URL_RE = /^(?:([\w.-]+:)?\/\/)?([\w.=&!~*'()%-]+)/i;
var ILLEGAL_CHARS_RE = /[=&!~*'()%]/;

function parseDomain(domain) {
  domain = domain && typeof domain === 'string' && domain.trim();
  if (!domain || domain.length > 256 || !URL_RE.test(domain)) {
    return;
  }
  domain =  RegExp.$2.toLowerCase();
  if (RegExp.$1 === 'root:') {
    return qs.parse(domain);
  }
  return ILLEGAL_CHARS_RE.test(domain) ? null : domain;
}

module.exports = function(req, res) {
  var domain = parseDomain(req.query.domain);
  if (!domain) {
    return res.status(400).end('Bad Request');
  }
  var isStr = typeof domain == 'string';
  var cert = isStr ? ca.createCertificate(domain) : ca.createRootCA(domain);
  var zip = new Zip();
  domain = isStr ? domain : 'root';
  var dir = domain + '/' + domain;
  zip.addFile(dir + '.crt', Buffer.from(cert.cert));
  zip.addFile(dir + '.key', Buffer(cert.key));
  zip.toBuffer(function(body) {
    res.attachment(domain + '.zip').send(body);
  }, function(err) {
    sendError(res, err);
  });
};


================================================
FILE: biz/webui/cgi-bin/custom-frames.js
================================================
var proxy = require('../lib/proxy');
var socketMgr = proxy.socketMgr;

module.exports = function(req, res) {
  var result = {};
  req.body.idList.forEach(function(reqId) {
    result[reqId] = socketMgr.getData(reqId);
  });
  req.body.frames.forEach(function(frame) {
    proxy.emit('frame', frame);
  });
  res.json(result);
};


================================================
FILE: biz/webui/cgi-bin/custom-handler.js
================================================
var config = require('../../../lib/config');

module.exports = function(req, res) {
  if (!config.customHandler) {
    return res.sendStatus(404);
  }
  config.customHandler(req, res);
};


================================================
FILE: biz/webui/cgi-bin/do-not-show-again.js
================================================
var properties = require('../../../lib/rules/util').properties;

module.exports = function(req, res) {
  properties.set('doNotShowAgainVersion', properties.getLatestVersion('latestVersion'));
  res.json({ec: 0, em: 'success'});
};




================================================
FILE: biz/webui/cgi-bin/download.js
================================================
var util = require('./util');

module.exports = function(req, res) {
  var body = req.body;
  var filename = body.filename;
  var headers = body.headers;
  var content = body.content;
  var type = body.type;
  var suffix = '.txt';
  if (type === 'log') {
    suffix = '.log';
  } else if (type === 'mock') {
    suffix = '.json';
  } else if (type === 'rawBase64') {
    type = 'base64';
    suffix = '';
  }

  if (!filename || typeof filename !== 'string') {
    filename = (type === 'mock' ? 'mock_' : 'text_') + util.formatDate() + suffix;
  } else if (!/\.\w+$/.test(filename)) {
    filename += suffix;
  }

  if (type === 'base64') {
    try {
      content = Buffer.from(content, 'base64');
    } catch (e) {}
  }
  if (headers) {
    headers += '\r\n\r\n';
    try {
      headers = Buffer.from(headers);
      if (Buffer.isBuffer(content)) {
        content = Buffer.concat([headers, content]);
        headers = null;
      }
    } catch (e) {}
    if (headers) {
      content = headers + (content || '');
    }
  }
  res.attachment(filename).send(content);
};


================================================
FILE: biz/webui/cgi-bin/enable-http2.js
================================================
var properties = require('../../../lib/rules/util').properties;

module.exports = function(req, res) {
  properties.setEnableHttp2(req.body.enableHttp2 == 1);
  res.json({ec: 0, em: 'success'});
};



================================================
FILE: biz/webui/cgi-bin/get-cert.js
================================================
var ca = require('../../../lib/https/ca');

var URL_RE = /^(?:(?:[\w.-]+:)?\/\/)?([\w.-]+)/i;

function parseDomain(domain) {
  domain = domain && typeof domain === 'string' && domain.trim();
  if (!domain || domain.length > 64 || !URL_RE.test(domain)) {
    return;
  }
  return RegExp.$1;
}

module.exports = function(req, res) {
  var domain = parseDomain(req.query.domain);
  if (!domain) {
    return res.status(400).end('Bad Request');
  }
  if (domain === 'rootCA') {
    return res.json(ca.getRootCA());
  }
  res.json(ca.createCertificate(domain.toLowerCase()));
};


================================================
FILE: biz/webui/cgi-bin/get-custom-certs-files.js
================================================
var getCustomCertsFiles = require('../../../lib/https/ca').getCustomCertsFiles;

module.exports = function(req, res) {
  res.json(getCustomCertsFiles());
};


================================================
FILE: biz/webui/cgi-bin/get-custom-certs-info.js
================================================
var getCustomCertsInfo = require('../../../lib/https/ca').getCustomCertsInfo;
// 给第三方用的,不能删除
module.exports = function(req, res) {
  res.json(getCustomCertsInfo());
};


================================================
FILE: biz/webui/cgi-bin/get-data.js
================================================
var proxy = require('../lib/proxy');
var util = require('./util');
var config = require('../../../lib/config');
var rulesUtil = require('../../../lib/rules/util');
var ca = require('../../../lib/https/ca');

var properties = rulesUtil.properties;
var rules = rulesUtil.rules;
var pluginMgr = proxy.pluginMgr;
var logger = proxy.logger;

module.exports = function(req, res) {
  var data = req.query;
  if (data.ids && typeof data.ids == 'string') {
    data.ids = data.ids.split(',');
    if (data.status && typeof data.status == 'string') {
      data.status = data.status.split(',');
    } else {
      data.status = null;
    }
  } else {
    data.ids = null;
  }
  var clientIp = util.getClientIp(req);
  var stopRecordConsole = data.startLogTime == -3;
  var stopRecordSvrLog = data.startSvrLogTime == -3;
  var h = req.headers;
  var curLogId = proxy.getLatestId();
  var curSvrLogId = logger.getLatestId();
  util.sendGzip(req, res, {
    ec: 0,
    wName: config.whistleName,
    disableInstaller: config.disableInstaller,
    account: config.account,
    version: config.version,
    installErrors: config.getInstallPluginErrors && config.getInstallPluginErrors(data.clientId),
    custom1: properties.get('Custom1'),
    custom2: properties.get('Custom2'),
    custom1Key: properties.get('Custom1Key'),
    custom2Key: properties.get('Custom2Key'),
    supportH2: config.enableH2,
    hasInvalidCerts: ca.hasInvalidCerts,
    clientIp: clientIp,
    mrulesClientId: config.mrulesClientId,
    mrulesTime: config.mrulesTime,
    mvaluesClientId: config.mvaluesClientId,
    mvaluesTime: config.mvaluesTime,
    server: util.getServerInfo(req),
    curLogId: stopRecordConsole ? undefined : curLogId,
    curSvrLogId: stopRecordSvrLog ? undefined : curSvrLogId,
    lastLogId: stopRecordConsole ? curLogId : undefined,
    lastSvrLogId: stopRecordSvrLog ? curSvrLogId : undefined,
    log: stopRecordConsole ? [] : proxy.getLogs(data.startLogTime, data.count, data.logId),
    svrLog: stopRecordSvrLog ? [] : logger.getLogs(data.startSvrLogTime, data.count),
    plugins: pluginMgr.getPlugins(),
    disabledPlugins: !config.notAllowedDisablePlugins && properties.get('disabledPlugins') || {},
    allowMultipleChoice: properties.get('allowMultipleChoice'),
    backRulesFirst: properties.get('backRulesFirst'),
    enabledCount: rules.getEnabledRules().length,
    disabledAllPlugins: !config.notAllowedDisablePlugins && properties.get('disabledAllPlugins'),
    disabledAllRules: !config.notAllowedDisableRules && properties.get('disabledAllRules'),
    interceptHttpsConnects: properties.isEnableCapture(),
    enableHttp2: properties.isEnableHttp2(),
    defaultRulesIsDisabled: rules.defaultRulesIsDisabled(),
    list: rules.getSelectedList(),
    data: proxy.getData(data, clientIp, h['x-whistle-filter-key'], h['x-whistle-filter-value'], h['x-whistle-filter-client-id'], h[config.CLIENT_ID_HEADER])
  });
};


================================================
FILE: biz/webui/cgi-bin/get-frames.js
================================================
var proxy = require('../lib/proxy');
var socketMgr = proxy.socketMgr;

module.exports = function(req, res) {
  var frames = proxy.getFrames(req.query);
  if (frames && !frames.length &&
      !socketMgr.exists(req.query.curReqId)) {
    frames = undefined;
  }
  res.json({
    ec: 0,
    frames: frames
  });
};


================================================
FILE: biz/webui/cgi-bin/get-session.js
================================================
var proxy = require('../lib/proxy');

var emptyArr = [];
var parseArray = function(str) {
  try {
    str = JSON.parse(str);
    return Array.isArray(str) ? str : emptyArr;
  } catch(e) {}
  return emptyArr;
};

module.exports = function(req, res) {
  var reqList = parseArray(req.query.reqList);
  var resList = parseArray(req.query.resList);
  var result = {};
  reqList.concat(resList).forEach(function(id) {
    if (result[id] != null) {
      return;
    }
    var item = proxy.getItem(id);
    if (!item) {
      result[id] = 0;
      return;
    }
    if ((item.requestTime && reqList.indexOf(id) !== -1) || item.endTime) {
      result[id] = item;
    }
  });
  res.json(result);
};


================================================
FILE: biz/webui/cgi-bin/hide-https-connects.js
================================================
module.exports = function(req, res) {
  res.json({ec: 0, em: 'success'});
};



================================================
FILE: biz/webui/cgi-bin/https-status.js
================================================
var properties = require('../../../lib/rules/util').properties;

module.exports = function(req, res) {
  res.json({
    ec: 0,
    enableCapture: properties.isEnableCapture(),
    enableHttp2: properties.isEnableHttp2()
  });
};


================================================
FILE: biz/webui/cgi-bin/import-remote.js
================================================
var util = require('../../../lib/util');
var loadService = require('../lib/proxy').loadService;

var MAX_LEN = 1024 * 1024 * 6;
var HTTP_RE = /https?:\/\/\S/i;

module.exports = function(req, res) {
  var url = req.query.url;
  if (HTTP_RE.test(url)) {
    util.request({
      url: url,
      maxLength: MAX_LEN
    }, function(err, body, r) {
      if (err) {
        var msg = err.code === 'EEXCEED'  ? 'The size of response body exceeds 6MB' : err.message;
        return res.json({ec: 2, em: msg});
      }
      var status = r.statusCode;
      if (status !== 200) {
        var em = status > 200 && status < 400 ? 'No data' : 'Request failed';
        return res.json({ec: 2, em: em + ' (statusCode: ' + status + ')'});
      }
      return res.json({ec: 0, body: body});
    });
  } else if (util.isString(url)) {
    loadService(function(err, options) {
      if (err) {
        util.sendRes(res, 500, err.stack || err);
      } else {
        req.url = '/cgi-bin/temp/get?filename=' + encodeURIComponent(url);
        util.transformReq(req, res, options.port);
      }
    });
  } else {
    res.json({ec: 400, em: 'Bad url'});
  }
};


================================================
FILE: biz/webui/cgi-bin/init.js
================================================
var g
Download .txt
gitextract_av_3ek6z/

├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc
├── .gitattributes
├── .gitignore
├── .npmignore
├── .travis.yml
├── CHANGELOG-en_US.md
├── CHANGELOG.md
├── LICENSE
├── README-en_US.md
├── README.md
├── assets/
│   ├── fiddler/
│   │   └── meta.xml
│   ├── js/
│   │   ├── log.js
│   │   ├── weinre.js
│   │   └── worker.js
│   ├── menu.html
│   ├── modal.html
│   └── tab.html
├── bin/
│   ├── ca/
│   │   ├── cli.js
│   │   ├── index.d.ts
│   │   └── index.js
│   ├── import.js
│   ├── plugin.d.ts
│   ├── plugin.js
│   ├── proxy.js
│   ├── status.js
│   ├── use.js
│   ├── util.js
│   └── whistle.js
├── biz/
│   ├── index.js
│   ├── init.js
│   ├── webui/
│   │   ├── cgi-bin/
│   │   │   ├── abort.js
│   │   │   ├── add-rules-values.js
│   │   │   ├── certs/
│   │   │   │   ├── active.js
│   │   │   │   ├── all.js
│   │   │   │   ├── remove.js
│   │   │   │   └── upload.js
│   │   │   ├── check-update.js
│   │   │   ├── cookies.js
│   │   │   ├── create-cert.js
│   │   │   ├── custom-frames.js
│   │   │   ├── custom-handler.js
│   │   │   ├── do-not-show-again.js
│   │   │   ├── download.js
│   │   │   ├── enable-http2.js
│   │   │   ├── get-cert.js
│   │   │   ├── get-custom-certs-files.js
│   │   │   ├── get-custom-certs-info.js
│   │   │   ├── get-data.js
│   │   │   ├── get-frames.js
│   │   │   ├── get-session.js
│   │   │   ├── hide-https-connects.js
│   │   │   ├── https-status.js
│   │   │   ├── import-remote.js
│   │   │   ├── init.js
│   │   │   ├── intercept-https-connects.js
│   │   │   ├── log/
│   │   │   │   └── set.js
│   │   │   ├── plugins/
│   │   │   │   ├── add-registry.js
│   │   │   │   ├── disable-all-plugins.js
│   │   │   │   ├── disable-plugin.js
│   │   │   │   ├── get-plugins.js
│   │   │   │   ├── is-enable.js
│   │   │   │   ├── registry-list.js
│   │   │   │   ├── uninstall.js
│   │   │   │   └── update-rules.js
│   │   │   ├── reset-local-address.js
│   │   │   ├── rootca.js
│   │   │   ├── rules/
│   │   │   │   ├── account.js
│   │   │   │   ├── add.js
│   │   │   │   ├── allow-multiple-choice.js
│   │   │   │   ├── disable-all-rules.js
│   │   │   │   ├── disable-default.js
│   │   │   │   ├── enable-back-rules-first.js
│   │   │   │   ├── enable-default.js
│   │   │   │   ├── enabled.js
│   │   │   │   ├── export.js
│   │   │   │   ├── import.js
│   │   │   │   ├── index.js
│   │   │   │   ├── list.js
│   │   │   │   ├── list2.js
│   │   │   │   ├── move-to.js
│   │   │   │   ├── project.js
│   │   │   │   ├── recycle/
│   │   │   │   │   ├── list.js
│   │   │   │   │   ├── remove.js
│   │   │   │   │   └── view.js
│   │   │   │   ├── remove.js
│   │   │   │   ├── rename.js
│   │   │   │   ├── select.js
│   │   │   │   ├── set-sys-hosts.js
│   │   │   │   └── unselect.js
│   │   │   ├── server-info.js
│   │   │   ├── set-custom-column.js
│   │   │   ├── set-dns-order.js
│   │   │   ├── socket/
│   │   │   │   ├── abort.js
│   │   │   │   ├── change-status.js
│   │   │   │   └── data.js
│   │   │   ├── status.js
│   │   │   ├── top.js
│   │   │   ├── util.js
│   │   │   └── values/
│   │   │       ├── add.js
│   │   │       ├── export.js
│   │   │       ├── get.js
│   │   │       ├── import.js
│   │   │       ├── index.js
│   │   │       ├── list.js
│   │   │       ├── list2.js
│   │   │       ├── move-to.js
│   │   │       ├── recycle/
│   │   │       │   ├── list.js
│   │   │       │   ├── remove.js
│   │   │       │   └── view.js
│   │   │       ├── remove.js
│   │   │       ├── rename.js
│   │   │       └── value.js
│   │   ├── htdocs/
│   │   │   ├── editor.html
│   │   │   ├── index.html
│   │   │   ├── js/
│   │   │   │   ├── decode.js
│   │   │   │   └── index.js
│   │   │   ├── preview.html
│   │   │   └── src/
│   │   │       ├── css/
│   │   │       │   ├── about.css
│   │   │       │   ├── base.css
│   │   │       │   ├── btn-group.css
│   │   │       │   ├── certs.css
│   │   │       │   ├── composer.css
│   │   │       │   ├── context-menu.css
│   │   │       │   ├── detail.css
│   │   │       │   ├── divider.css
│   │   │       │   ├── dropdown.css
│   │   │       │   ├── editor-settings.css
│   │   │       │   ├── editor.css
│   │   │       │   ├── files-dialog.css
│   │   │       │   ├── filter-input.css
│   │   │       │   ├── frames.css
│   │   │       │   ├── iframe-dialog.css
│   │   │       │   ├── iframe.css
│   │   │       │   ├── image-view.css
│   │   │       │   ├── import-dialog.css
│   │   │       │   ├── index.css
│   │   │       │   ├── json-viewer.css
│   │   │       │   ├── kv.css
│   │   │       │   ├── large-dialog.css
│   │   │       │   ├── list-dialog.css
│   │   │       │   ├── list.css
│   │   │       │   ├── menu-item.css
│   │   │       │   ├── message.css
│   │   │       │   ├── modal.css
│   │   │       │   ├── network-settings.css
│   │   │       │   ├── online.css
│   │   │       │   ├── override.css
│   │   │       │   ├── overview.css
│   │   │       │   ├── plugins-mgr.css
│   │   │       │   ├── plugins.css
│   │   │       │   ├── properties.css
│   │   │       │   ├── props-editor.css
│   │   │       │   ├── record-btn.css
│   │   │       │   ├── req-data.css
│   │   │       │   ├── req-detail.css
│   │   │       │   ├── res-detail.css
│   │   │       │   ├── service.css
│   │   │       │   ├── sync-dialog.css
│   │   │       │   ├── table.css
│   │   │       │   ├── textarea.css
│   │   │       │   ├── theme.css
│   │   │       │   ├── timeline.css
│   │   │       │   └── tools.css
│   │   │       ├── js/
│   │   │       │   ├── about.js
│   │   │       │   ├── base-css.js
│   │   │       │   ├── bridge.js
│   │   │       │   ├── btn-group.js
│   │   │       │   ├── certs-info-dialog.js
│   │   │       │   ├── cgi.js
│   │   │       │   ├── close-btn.js
│   │   │       │   ├── columns.js
│   │   │       │   ├── components/
│   │   │       │   │   ├── json/
│   │   │       │   │   │   ├── index.js
│   │   │       │   │   │   ├── parse.js
│   │   │       │   │   │   └── stringify.js
│   │   │       │   │   └── react-json-tree/
│   │   │       │   │       ├── ItemRange.js
│   │   │       │   │       ├── JSONArrayNode.js
│   │   │       │   │       ├── JSONArrow.js
│   │   │       │   │       ├── JSONIterableNode.js
│   │   │       │   │       ├── JSONNestedNode.js
│   │   │       │   │       ├── JSONNode.js
│   │   │       │   │       ├── JSONObjectNode.js
│   │   │       │   │       ├── JSONValueNode.js
│   │   │       │   │       ├── createStylingFromTheme.js
│   │   │       │   │       ├── getCollectionEntries.js
│   │   │       │   │       ├── index.js
│   │   │       │   │       ├── objType.js
│   │   │       │   │       ├── themes/
│   │   │       │   │       │   └── solarized.js
│   │   │       │   │       └── utils/
│   │   │       │   │           └── hexToRgb.js
│   │   │       │   ├── composer-list.js
│   │   │       │   ├── composer.js
│   │   │       │   ├── console.js
│   │   │       │   ├── context-menu.js
│   │   │       │   ├── cookies-dialog.js
│   │   │       │   ├── copy-btn.js
│   │   │       │   ├── data-center.js
│   │   │       │   ├── decode.js
│   │   │       │   ├── detail.js
│   │   │       │   ├── dialog.js
│   │   │       │   ├── divider.js
│   │   │       │   ├── dns-servers-dialog.js
│   │   │       │   ├── dropdown.js
│   │   │       │   ├── editor-dialog.js
│   │   │       │   ├── editor-settings.js
│   │   │       │   ├── editor.js
│   │   │       │   ├── empty.js
│   │   │       │   ├── enable-https-btn.js
│   │   │       │   ├── enabled-rules.js
│   │   │       │   ├── events.js
│   │   │       │   ├── expand-collapse.js
│   │   │       │   ├── export-dialog.js
│   │   │       │   ├── filter-btn.js
│   │   │       │   ├── filter-input.js
│   │   │       │   ├── forward-back-btn.js
│   │   │       │   ├── frame-composer.js
│   │   │       │   ├── frame-data.js
│   │   │       │   ├── frame-list.js
│   │   │       │   ├── frame-modal.js
│   │   │       │   ├── frames.js
│   │   │       │   ├── github-icon.js
│   │   │       │   ├── help-icon.js
│   │   │       │   ├── history-data.js
│   │   │       │   ├── https-settings.js
│   │   │       │   ├── icon.js
│   │   │       │   ├── iframe-dialog.js
│   │   │       │   ├── iframe.js
│   │   │       │   ├── iframes.js
│   │   │       │   ├── image-view.js
│   │   │       │   ├── import-dialog.js
│   │   │       │   ├── index.js
│   │   │       │   ├── inspector.js
│   │   │       │   ├── inspectors.js
│   │   │       │   ├── is-utf8.js
│   │   │       │   ├── json-dialog.js
│   │   │       │   ├── json-viewer.js
│   │   │       │   ├── kv-dialog.js
│   │   │       │   ├── large-dialog.js
│   │   │       │   ├── lazy-init.js
│   │   │       │   ├── list-dialog.js
│   │   │       │   ├── list-modal.js
│   │   │       │   ├── list.js
│   │   │       │   ├── menu-item.js
│   │   │       │   ├── message.js
│   │   │       │   ├── mock-dialog.js
│   │   │       │   ├── modal.js
│   │   │       │   ├── network-modal.js
│   │   │       │   ├── network-settings.js
│   │   │       │   ├── network.js
│   │   │       │   ├── online.js
│   │   │       │   ├── order-table.js
│   │   │       │   ├── overview.js
│   │   │       │   ├── panel-tips.js
│   │   │       │   ├── parse-curl.js
│   │   │       │   ├── parse-rules.js
│   │   │       │   ├── plugins-mgr.js
│   │   │       │   ├── plugins-tabs.js
│   │   │       │   ├── plugins.js
│   │   │       │   ├── properties.js
│   │   │       │   ├── props-editor.js
│   │   │       │   ├── protocols.js
│   │   │       │   ├── qrcode-dialog.js
│   │   │       │   ├── qrcode.js
│   │   │       │   ├── record-btn.js
│   │   │       │   ├── recycle-bin.js
│   │   │       │   ├── req-data.js
│   │   │       │   ├── req-detail.js
│   │   │       │   ├── res-detail.js
│   │   │       │   ├── rule-list.js
│   │   │       │   ├── rules-dialog.js
│   │   │       │   ├── rules-hint.js
│   │   │       │   ├── rules-mode.js
│   │   │       │   ├── saved.js
│   │   │       │   ├── server-log.js
│   │   │       │   ├── service-btn.js
│   │   │       │   ├── service-dialog.js
│   │   │       │   ├── share-via-url-btn.js
│   │   │       │   ├── shortcuts-settings.js
│   │   │       │   ├── storage.js
│   │   │       │   ├── sync-dialog.js
│   │   │       │   ├── tab-frame.js
│   │   │       │   ├── tab-mgr.js
│   │   │       │   ├── table.js
│   │   │       │   ├── tabs.js
│   │   │       │   ├── teleport.js
│   │   │       │   ├── text-dialog.js
│   │   │       │   ├── textarea.js
│   │   │       │   ├── textview.js
│   │   │       │   ├── timeline.js
│   │   │       │   ├── tips-dialog.js
│   │   │       │   ├── tool-box.js
│   │   │       │   ├── tools.js
│   │   │       │   ├── update-all-btn.js
│   │   │       │   ├── util.js
│   │   │       │   ├── view-inspector.js
│   │   │       │   ├── win.js
│   │   │       │   └── workers.js
│   │   │       └── webpack.config.js
│   │   ├── htdocs.js
│   │   └── lib/
│   │       ├── index.js
│   │       └── proxy.js
│   └── weinre/
│       ├── index.js
│       └── server.js
├── docs/
│   ├── .vitepress/
│   │   └── config.mts
│   ├── docs/
│   │   ├── cli.md
│   │   ├── extensions/
│   │   │   ├── dev.md
│   │   │   ├── npm.md
│   │   │   └── usage.md
│   │   ├── faq.md
│   │   ├── getting-started.md
│   │   ├── gui/
│   │   │   ├── composer.md
│   │   │   ├── console.md
│   │   │   ├── https.md
│   │   │   ├── network.md
│   │   │   ├── online.md
│   │   │   ├── plugins.md
│   │   │   ├── rules.md
│   │   │   ├── shortcut.md
│   │   │   ├── values.md
│   │   │   └── weinre.md
│   │   ├── index.md
│   │   ├── mobile.md
│   │   └── rules/
│   │       ├── @.md
│   │       ├── attachment.md
│   │       ├── auth.md
│   │       ├── cache.md
│   │       ├── cipher.md
│   │       ├── cssAppend.md
│   │       ├── cssBody.md
│   │       ├── cssPrepend.md
│   │       ├── delete.md
│   │       ├── disable.md
│   │       ├── enable.md
│   │       ├── excludeFilter.md
│   │       ├── file.md
│   │       ├── filters.md
│   │       ├── forwardedFor.md
│   │       ├── frameScript.md
│   │       ├── headerReplace.md
│   │       ├── host.md
│   │       ├── htmlAppend.md
│   │       ├── htmlBody.md
│   │       ├── htmlPrepend.md
│   │       ├── http.md
│   │       ├── https-proxy.md
│   │       ├── https.md
│   │       ├── ignore.md
│   │       ├── includeFilter.md
│   │       ├── inherit.md
│   │       ├── jsAppend.md
│   │       ├── jsBody.md
│   │       ├── jsPrepend.md
│   │       ├── lineProps.md
│   │       ├── locationHref.md
│   │       ├── log.md
│   │       ├── method.md
│   │       ├── operation.md
│   │       ├── pac.md
│   │       ├── pathReplace.md
│   │       ├── pattern.md
│   │       ├── pipe.md
│   │       ├── plugin-vars.md
│   │       ├── protocols.md
│   │       ├── proxy.md
│   │       ├── rawfile.md
│   │       ├── redirect.md
│   │       ├── referer.md
│   │       ├── replaceStatus.md
│   │       ├── reqAppend.md
│   │       ├── reqBody.md
│   │       ├── reqCharset.md
│   │       ├── reqCookies.md
│   │       ├── reqCors.md
│   │       ├── reqDelay.md
│   │       ├── reqHeaders.md
│   │       ├── reqMerge.md
│   │       ├── reqPrepend.md
│   │       ├── reqReplace.md
│   │       ├── reqRules.md
│   │       ├── reqScript.md
│   │       ├── reqSpeed.md
│   │       ├── reqType.md
│   │       ├── reqWrite.md
│   │       ├── reqWriteRaw.md
│   │       ├── resAppend.md
│   │       ├── resBody.md
│   │       ├── resCharset.md
│   │       ├── resCookies.md
│   │       ├── resCors.md
│   │       ├── resDelay.md
│   │       ├── resHeaders.md
│   │       ├── resMerge.md
│   │       ├── resPrepend.md
│   │       ├── resReplace.md
│   │       ├── resRules.md
│   │       ├── resScript.md
│   │       ├── resSpeed.md
│   │       ├── resType.md
│   │       ├── resWrite.md
│   │       ├── resWriteRaw.md
│   │       ├── responseFor.md
│   │       ├── rule.md
│   │       ├── skip.md
│   │       ├── sniCallback.md
│   │       ├── socks.md
│   │       ├── statusCode.md
│   │       ├── style.md
│   │       ├── tpl.md
│   │       ├── trailers.md
│   │       ├── tunnel.md
│   │       ├── ua.md
│   │       ├── urlParams.md
│   │       ├── weinre.md
│   │       ├── ws.md
│   │       ├── wss.md
│   │       ├── xfile.md
│   │       ├── xhost.md
│   │       ├── xhttps-proxy.md
│   │       ├── xproxy.md
│   │       ├── xrawfile.md
│   │       ├── xsocks.md
│   │       └── xtpl.md
│   ├── en/
│   │   ├── docs/
│   │   │   ├── cli.md
│   │   │   ├── extensions/
│   │   │   │   ├── dev.md
│   │   │   │   ├── npm.md
│   │   │   │   └── usage.md
│   │   │   ├── faq.md
│   │   │   ├── getting-started.md
│   │   │   ├── gui/
│   │   │   │   ├── composer.md
│   │   │   │   ├── console.md
│   │   │   │   ├── https.md
│   │   │   │   ├── network.md
│   │   │   │   ├── online.md
│   │   │   │   ├── plugins.md
│   │   │   │   ├── rules.md
│   │   │   │   ├── shortcut.md
│   │   │   │   ├── values.md
│   │   │   │   └── weinre.md
│   │   │   ├── index.md
│   │   │   ├── mobile.md
│   │   │   └── rules/
│   │   │       ├── @.md
│   │   │       ├── attachment.md
│   │   │       ├── auth.md
│   │   │       ├── cache.md
│   │   │       ├── cipher.md
│   │   │       ├── cssAppend.md
│   │   │       ├── cssBody.md
│   │   │       ├── cssPrepend.md
│   │   │       ├── delete.md
│   │   │       ├── disable.md
│   │   │       ├── enable.md
│   │   │       ├── excludeFilter.md
│   │   │       ├── file.md
│   │   │       ├── filters.md
│   │   │       ├── forwardedFor.md
│   │   │       ├── frameScript.md
│   │   │       ├── headerReplace.md
│   │   │       ├── host.md
│   │   │       ├── htmlAppend.md
│   │   │       ├── htmlBody.md
│   │   │       ├── htmlPrepend.md
│   │   │       ├── http.md
│   │   │       ├── https-proxy.md
│   │   │       ├── https.md
│   │   │       ├── ignore.md
│   │   │       ├── includeFilter.md
│   │   │       ├── inherit.md
│   │   │       ├── jsAppend.md
│   │   │       ├── jsBody.md
│   │   │       ├── jsPrepend.md
│   │   │       ├── lineProps.md
│   │   │       ├── locationHref.md
│   │   │       ├── log.md
│   │   │       ├── method.md
│   │   │       ├── operation.md
│   │   │       ├── pac.md
│   │   │       ├── pathReplace.md
│   │   │       ├── pattern.md
│   │   │       ├── pipe.md
│   │   │       ├── plugin-vars.md
│   │   │       ├── protocols.md
│   │   │       ├── proxy.md
│   │   │       ├── rawfile.md
│   │   │       ├── redirect.md
│   │   │       ├── referer.md
│   │   │       ├── replaceStatus.md
│   │   │       ├── reqAppend.md
│   │   │       ├── reqBody.md
│   │   │       ├── reqCharset.md
│   │   │       ├── reqCookies.md
│   │   │       ├── reqCors.md
│   │   │       ├── reqDelay.md
│   │   │       ├── reqHeaders.md
│   │   │       ├── reqMerge.md
│   │   │       ├── reqPrepend.md
│   │   │       ├── reqReplace.md
│   │   │       ├── reqRules.md
│   │   │       ├── reqScript.md
│   │   │       ├── reqSpeed.md
│   │   │       ├── reqType.md
│   │   │       ├── reqWrite.md
│   │   │       ├── reqWriteRaw.md
│   │   │       ├── resAppend.md
│   │   │       ├── resBody.md
│   │   │       ├── resCharset.md
│   │   │       ├── resCookies.md
│   │   │       ├── resCors.md
│   │   │       ├── resDelay.md
│   │   │       ├── resHeaders.md
│   │   │       ├── resMerge.md
│   │   │       ├── resPrepend.md
│   │   │       ├── resReplace.md
│   │   │       ├── resRules.md
│   │   │       ├── resScript.md
│   │   │       ├── resSpeed.md
│   │   │       ├── resType.md
│   │   │       ├── resWrite.md
│   │   │       ├── resWriteRaw.md
│   │   │       ├── responseFor.md
│   │   │       ├── rule.md
│   │   │       ├── skip.md
│   │   │       ├── sniCallback.md
│   │   │       ├── socks.md
│   │   │       ├── statusCode.md
│   │   │       ├── style.md
│   │   │       ├── tpl.md
│   │   │       ├── trailers.md
│   │   │       ├── tunnel.md
│   │   │       ├── ua.md
│   │   │       ├── urlParams.md
│   │   │       ├── weinre.md
│   │   │       ├── ws.md
│   │   │       ├── wss.md
│   │   │       ├── xfile.md
│   │   │       ├── xhost.md
│   │   │       ├── xhttps-proxy.md
│   │   │       ├── xproxy.md
│   │   │       ├── xrawfile.md
│   │   │       ├── xsocks.md
│   │   │       └── xtpl.md
│   │   └── index.md
│   └── index.md
├── index.d.ts
├── index.js
├── lib/
│   ├── config.js
│   ├── handlers/
│   │   ├── error-handler.js
│   │   ├── file-proxy.js
│   │   ├── http-proxy.js
│   │   └── index.js
│   ├── https/
│   │   ├── ca.js
│   │   ├── h2.js
│   │   ├── index.js
│   │   └── load-cert.js
│   ├── index.js
│   ├── init.js
│   ├── inspectors/
│   │   ├── data.js
│   │   ├── index.js
│   │   ├── log.js
│   │   ├── req.js
│   │   ├── res.js
│   │   ├── rules.js
│   │   └── weinre.js
│   ├── plugins/
│   │   ├── compat.js
│   │   ├── get-plugins-sync.js
│   │   ├── get-plugins.js
│   │   ├── index.js
│   │   ├── load-plugin.js
│   │   ├── module-paths.js
│   │   ├── proxy.js
│   │   ├── shared-storage.js
│   │   └── util.js
│   ├── rules/
│   │   ├── dns.js
│   │   ├── index.js
│   │   ├── protocols.js
│   │   ├── recycle-bin.js
│   │   ├── rules.js
│   │   ├── storage.js
│   │   └── util.js
│   ├── service/
│   │   ├── compose-data.js
│   │   ├── composer.js
│   │   ├── data-center.js
│   │   ├── extract-saz.js
│   │   ├── generate-saz.js
│   │   ├── index.js
│   │   ├── install.js
│   │   ├── service.js
│   │   └── util.js
│   ├── socket-mgr.js
│   ├── tunnel.js
│   ├── upgrade.js
│   └── util/
│       ├── common.js
│       ├── data-server.js
│       ├── drain.js
│       ├── file-mgr.js
│       ├── file-writer-transform.js
│       ├── http-mgr.js
│       ├── index.js
│       ├── is-utf8.js
│       ├── log-server.js
│       ├── logger.js
│       ├── parse-query.js
│       ├── parse-url-safe.js
│       ├── parse-url.js
│       ├── patch.js
│       ├── perf.js
│       ├── process.js
│       ├── replace-pattern-transform.js
│       ├── replace-string-transform.js
│       ├── speed-transform.js
│       ├── transproto.js
│       ├── whistle-transform.js
│       └── zlib.js
├── package.json
├── require.js
└── test/
    ├── assets/
    │   ├── certs/
    │   │   ├── _.cert.w2.org.crt
    │   │   ├── _.cert.w2.org.key
    │   │   ├── _root.crt
    │   │   ├── cert.w2.org.key
    │   │   ├── root.key
    │   │   ├── test.crt
    │   │   └── test.key
    │   ├── files/
    │   │   ├── 1.txt
    │   │   ├── 2.txt
    │   │   ├── 3.txt
    │   │   ├── empty.txt
    │   │   ├── gb2312.txt
    │   │   ├── mock-remote-key.txt
    │   │   ├── mock-script-key.txt
    │   │   ├── rules.txt
    │   │   ├── service-remote-key.txt
    │   │   ├── service-script-key.txt
    │   │   ├── shadow-remote-key.txt
    │   │   ├── shadow-script-key.txt
    │   │   ├── storage/
    │   │   │   ├── .backup/
    │   │   │   │   ├── 1.test1.tx
    │   │   │   │   ├── 2.test2.tx
    │   │   │   │   ├── 3.test3.tx
    │   │   │   │   └── properties
    │   │   │   ├── files/
    │   │   │   │   ├── 1.test1.tx
    │   │   │   │   ├── 2.test2.tx
    │   │   │   │   └── 3.test3.tx
    │   │   │   └── properties
    │   │   └── test.txt
    │   ├── rules/
    │   │   ├── mock.txt
    │   │   ├── service.txt
    │   │   └── shadow.txt
    │   └── values/
    │       ├── json5.txt
    │       ├── rawFile.html
    │       ├── rawFile2.js
    │       ├── reqScript.js
    │       ├── resScript.js
    │       ├── rulesFile.js
    │       ├── rulesFile.txt
    │       ├── rulesFile2.js
    │       ├── test.json
    │       ├── test.txt
    │       ├── test2.json
    │       ├── test3.json
    │       ├── tps.rules
    │       ├── tps1.json
    │       └── tps2.json
    ├── config.test.js
    ├── events.js
    ├── index.test.js
    ├── plugins/
    │   ├── @test/
    │   │   └── whistle.test3/
    │   │       ├── index.js
    │   │       ├── package.json
    │   │       ├── rules.txt
    │   │       └── test/
    │   │           └── abc/
    │   │               ├── abc/
    │   │               │   └── index.html
    │   │               └── index.html
    │   ├── whistle.pass/
    │   │   ├── index.js
    │   │   └── package.json
    │   ├── whistle.pipe-http/
    │   │   ├── index.js
    │   │   ├── lib/
    │   │   │   ├── assert.js
    │   │   │   ├── reqReadServer.js
    │   │   │   ├── reqWriteServer.js
    │   │   │   ├── resReadServer.js
    │   │   │   └── resWriteServer.js
    │   │   ├── package.json
    │   │   └── rules.txt
    │   ├── whistle.pipe-tunnel/
    │   │   ├── index.js
    │   │   ├── lib/
    │   │   │   ├── assert.js
    │   │   │   ├── tunnelReqRead.js
    │   │   │   ├── tunnelReqWrite.js
    │   │   │   ├── tunnelResRead.js
    │   │   │   └── tunnelResWrite.js
    │   │   ├── package.json
    │   │   └── rules.txt
    │   ├── whistle.pipe-ws/
    │   │   ├── index.js
    │   │   ├── lib/
    │   │   │   ├── assert.js
    │   │   │   ├── wsReqRead.js
    │   │   │   ├── wsReqWrite.js
    │   │   │   ├── wsResRead.js
    │   │   │   └── wsResWrite.js
    │   │   ├── package.json
    │   │   └── rules.txt
    │   ├── whistle.test/
    │   │   ├── _rules.txt
    │   │   ├── assets/
    │   │   │   ├── dispatch.js
    │   │   │   ├── files/
    │   │   │   │   ├── append.txt
    │   │   │   │   ├── bin/
    │   │   │   │   │   ├── body.txt
    │   │   │   │   │   ├── bottom.txt
    │   │   │   │   │   ├── file.txt
    │   │   │   │   │   └── top.txt
    │   │   │   │   ├── body.txt
    │   │   │   │   ├── css.css
    │   │   │   │   ├── html.html
    │   │   │   │   ├── index.html
    │   │   │   │   ├── js.js
    │   │   │   │   ├── log.js
    │   │   │   │   ├── pac.js
    │   │   │   │   ├── prepend.txt
    │   │   │   │   ├── rawfile.html
    │   │   │   │   ├── ssi-include.html
    │   │   │   │   ├── ssi1.html
    │   │   │   │   ├── ssi2.html
    │   │   │   │   ├── ssi3.html
    │   │   │   │   └── tpl.js
    │   │   │   └── values/
    │   │   │       ├── headers.json
    │   │   │       ├── replace.json
    │   │   │       ├── req.json
    │   │   │       ├── reqCookies.json
    │   │   │       ├── reqCors.json
    │   │   │       ├── res.json
    │   │   │       ├── resCookies.json
    │   │   │       ├── resCors.json
    │   │   │       ├── upload.json
    │   │   │       ├── urlParams.json
    │   │   │       └── urlReplace.json
    │   │   ├── index.js
    │   │   ├── lib/
    │   │   │   ├── resRulesServer.js
    │   │   │   ├── rulesServer.js
    │   │   │   ├── server.js
    │   │   │   ├── statusServer.js
    │   │   │   ├── tunnelRulesServer.js
    │   │   │   ├── tunnelServer.js
    │   │   │   ├── uiServer.js
    │   │   │   └── util.js
    │   │   ├── package.json
    │   │   └── rules.txt
    │   ├── whistle.test-values/
    │   │   ├── index.js
    │   │   ├── package.json
    │   │   └── rules.txt
    │   ├── whistle.test1/
    │   │   ├── _rules.txt
    │   │   ├── index.js
    │   │   ├── lib/
    │   │   │   └── rulesServer.js
    │   │   ├── package.json
    │   │   └── rules.txt
    │   └── whistle.test2/
    │       ├── _rules.txt
    │       ├── index.js
    │       ├── package.json
    │       ├── rules.txt
    │       └── test.txt
    ├── proxy/
    │   ├── disable.test.js
    │   └── enable.test.js
    ├── rules.txt
    ├── units/
    │   ├── _normalizeConnectArgs.test.js
    │   ├── attachment.test.js
    │   ├── auth.test.js
    │   ├── cache.test.js
    │   ├── common.test.js
    │   ├── composer.test.js
    │   ├── connect.test.js
    │   ├── css.test.js
    │   ├── delete.test.js
    │   ├── disable.test.js
    │   ├── file.test.js
    │   ├── filter.test.js
    │   ├── fm.test.js
    │   ├── forward.test.js
    │   ├── host.test.js
    │   ├── html.test.js
    │   ├── https.test.js
    │   ├── ignore.test.js
    │   ├── insertFile.test.js
    │   ├── js.test.js
    │   ├── keys.test.js
    │   ├── log.test.js
    │   ├── method.test.js
    │   ├── options.test.js
    │   ├── others.test.js
    │   ├── pac.test.js
    │   ├── params.test.js
    │   ├── plugin.test.js
    │   ├── plugins.test.js
    │   ├── proxy.test.js
    │   ├── range.test.js
    │   ├── rawfile.test.js
    │   ├── redirect.test.js
    │   ├── referer.test.js
    │   ├── replaceStatus.test.js
    │   ├── req.prepend.body.append.test.js
    │   ├── reqAppend.test.js
    │   ├── reqBody.test.js
    │   ├── reqCharset.test.js
    │   ├── reqCookies.test.js
    │   ├── reqCors.test.js
    │   ├── reqDelay.test.js
    │   ├── reqHeaders.test.js
    │   ├── reqPrepend.test.js
    │   ├── reqReplace.test.js
    │   ├── reqSpeed.test.js
    │   ├── reqType.test.js
    │   ├── res.prepend.body.append.test.js
    │   ├── resAppend.test.js
    │   ├── resBody.test.js
    │   ├── resCharset.test.js
    │   ├── resCookies.test.js
    │   ├── resCors.test.js
    │   ├── resDelay.test.js
    │   ├── resHeaders.test.js
    │   ├── resPrepend.test.js
    │   ├── resReplace.test.js
    │   ├── resSpeed.test.js
    │   ├── resType.test.js
    │   ├── rule.test.js
    │   ├── rulesFile.test.js
    │   ├── script.test.js
    │   ├── socks.test.js
    │   ├── ssi-include.test.js
    │   ├── statusCode.test.js
    │   ├── tpl.test.js
    │   ├── tplStr.test.js
    │   ├── tps.test.js
    │   ├── tunnel.test.js
    │   ├── tunnelPolicy.test.js
    │   ├── ua.test.js
    │   ├── ui.test.js
    │   ├── urlParams.test.js
    │   ├── urlReplace.test.js
    │   ├── utils.test.js
    │   ├── values.test.js
    │   ├── var.test.js
    │   ├── weinre.test.js
    │   ├── wildcard.test.js
    │   ├── write.test.js
    │   ├── ws.test.js
    │   └── xfile.test.js
    └── util.test.js
Download .txt
Showing preview only (271K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (3131 symbols across 146 files)

FILE: assets/js/log.js
  function patchJSON (line 13) | function patchJSON() {
  function stringify (line 206) | function stringify(obj) {
  function getPathPrefix (line 224) | function getPathPrefix() {
  function addLog (line 242) | function addLog(level, text) {
  function getPageInfo (line 270) | function getPageInfo() {
  function getErrorStack (line 274) | function getErrorStack(error, message) {
  function arrayIndexOf (line 286) | function arrayIndexOf(arr, value) {
  function stringifyObj (line 298) | function stringifyObj(obj) {

FILE: assets/js/worker.js
  function t (line 19) | function t(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,lo...
  function r (line 19) | function r(e){try{return i(e)}catch(t){}}
  function n (line 19) | function n(e){var t=e.length;if(t%4>0)throw new Error("Invalid string. L...
  function r (line 19) | function r(e){var t=n(e),r=t[0],o=t[1];return 3*(r+o)/4-o}
  function o (line 19) | function o(e,t,n){return 3*(t+n)/4-n}
  function i (line 19) | function i(e){var t,r,i=n(e),a=i[0],s=i[1],l=new d(o(e,a,s)),c=0,p=s>0?a...
  function a (line 19) | function a(e){return c[e>>18&63]+c[e>>12&63]+c[e>>6&63]+c[63&e]}
  function s (line 19) | function s(e,t,n){for(var r,o=[],i=t;n>i;i+=3)r=(e[i]<<16&16711680)+(e[i...
  function l (line 19) | function l(e){for(var t,n=e.length,r=n%3,o=[],i=16383,a=0,l=n-r;l>a;a+=i...
  function n (line 19) | function n(e,t){t=t||0;for(var n=Math.min(e.length,r);n>t;t++){var o=e[t...

FILE: bin/ca/cli.js
  function installCert (line 16) | function installCert(certFile, url) {
  function install (line 25) | function install(addr, useDefault) {

FILE: bin/ca/index.js
  function checkSuccess (line 8) | function checkSuccess(result) {
  function getKeyChain (line 15) | function getKeyChain() {
  function installMac (line 21) | function installMac(certPath) {
  function installWin (line 31) | function installWin(certFile) {
  function getCAConfig (line 42) | function getCAConfig() {
  function installLinux (line 56) | function installLinux(certFile, execFunc) {

FILE: bin/import.js
  function importModle (line 3) | function importModle(filepath, callback) {

FILE: bin/plugin.js
  function getInstallPath (line 20) | function getInstallPath(name, dir) {
  function removeDirSync (line 24) | function removeDirSync(installPath) {
  function removeTempFiles (line 30) | function removeTempFiles(argv) {
  function renameDirSync (line 38) | function renameDirSync(installPath, realPath) {
  function getTempName (line 44) | function getTempName(name) {
  function formatCmdOptions (line 54) | function formatCmdOptions(options) {
  function getValue (line 64) | function getValue(str) {
  function parseDir (line 72) | function parseDir(dir) {
  function getInstallDir (line 88) | function getInstallDir(argv) {
  function getPluginNameFormDeps (line 108) | function getPluginNameFormDeps(deps) {
  function getPkgName (line 117) | function getPkgName(name) {
  function install (line 124) | function install(cmd, name, argv, ver, pluginsCache, callback, handleErr...
  function getRegistry (line 207) | function getRegistry(argv) {
  function installPlugins (line 219) | function installPlugins(cmd, plugins, argv, pluginsCache, deep, handleEr...

FILE: bin/proxy.js
  function showInfo (line 11) | function showInfo(msg) {
  function showError (line 17) | function showError(msg) {
  function enableProxy (line 23) | function enableProxy(options) {
  function disableProxy (line 36) | function disableProxy(sudo) {

FILE: bin/status.js
  function showAll (line 11) | function showAll(byStop) {

FILE: bin/use.js
  function showStartWhistleTips (line 18) | function showStartWhistleTips(storage, isClient) {
  function handleRules (line 26) | function handleRules(filepath, callback, port) {
  function getString (line 42) | function getString(str) {
  function existsPlugin (line 46) | function existsPlugin(name) {
  function request (line 61) | function request(body, callback) {
  function checkDefault (line 88) | function checkDefault(running, storage, isClient, callback) {
  function readClientConfig (line 112) | function readClientConfig() {

FILE: bin/util.js
  function isRunning (line 24) | function isRunning(pid, callback) {
  function getIpList (line 34) | function getIpList() {
  function error (line 52) | function error(msg) {
  function warn (line 56) | function warn(msg) {
  function info (line 60) | function info(msg) {
  function showKillError (line 67) | function showKillError() {
  function showUsage (line 74) | function showUsage(isRunning, options, restart) {
  function getDataDir (line 123) | function getDataDir() {
  function formatOptions (line 127) | function formatOptions(options) {
  function readConfig (line 139) | function readConfig(storage) {
  function readConfigList (line 147) | function readConfigList() {
  function getBody (line 182) | function getBody(res, callback) {

FILE: bin/whistle.js
  function getLatestVersion (line 19) | function getLatestVersion(options, cb, index) {
  function handleEnd (line 43) | function handleEnd(err, options, restart, run) {
  function showStartupInfo (line 63) | function showStartupInfo(err, options, debugMode, restart) {
  function getName (line 81) | function getName() {

FILE: biz/index.js
  function transformUI (line 24) | function transformUI(req, res) {

FILE: biz/webui/cgi-bin/abort.js
  function abort (line 4) | function abort(reqId) {

FILE: biz/webui/cgi-bin/create-cert.js
  function parseDomain (line 9) | function parseDomain(domain) {

FILE: biz/webui/cgi-bin/get-cert.js
  function parseDomain (line 5) | function parseDomain(domain) {

FILE: biz/webui/cgi-bin/set-custom-column.js
  function updateName (line 5) | function updateName(name, value, key) {

FILE: biz/webui/cgi-bin/util.js
  function formatDate (line 122) | function formatDate() {
  function sendError (line 139) | function sendError(res, err) {

FILE: biz/webui/htdocs.js
  function getHtmlFile (line 4) | function getHtmlFile(file) {
  function getImgFile (line 10) | function getImgFile(file) {
  function getJsFile (line 16) | function getJsFile(file) {

FILE: biz/webui/htdocs/js/decode.js
  function t (line 1) | function t(e){if(n[e])return n[e].exports;var o=n[e]={exports:{},id:e,lo...
  function e (line 1) | function e(r){try{return u(r)}catch(t){}}
  function n (line 1) | function n(r){var t=r.length;if(t%4>0)throw new Error("Invalid string. L...
  function e (line 1) | function e(r){var t=n(r),e=t[0],o=t[1];return 3*(e+o)/4-o}
  function o (line 1) | function o(r,t,n){return 3*(t+n)/4-n}
  function u (line 1) | function u(r){var t,e,u=n(r),a=u[0],c=u[1],i=new d(o(r,a,c)),f=0,s=c>0?a...
  function a (line 1) | function a(r){return f[r>>18&63]+f[r>>12&63]+f[r>>6&63]+f[63&r]}
  function c (line 1) | function c(r,t,n){for(var e,o=[],u=t;n>u;u+=3)e=(r[u]<<16&16711680)+(r[u...
  function i (line 1) | function i(r){for(var t,n=r.length,e=n%3,o=[],u=16383,a=0,i=n-e;i>a;a+=u...
  function n (line 1) | function n(r,t){t=t||0;for(var n=Math.min(r.length,e);n>t;t++){var o=r[t...

FILE: biz/webui/htdocs/js/index.js
  function t (line 1) | function t(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,lo...
  function r (line 1) | function r(e){return e?be:null}
  function o (line 1) | function o(e){return"string"==typeof e?e.trim():""}
  function i (line 1) | function i(e){if(!De.test(e))return!1;var t=z.isWin?/^(?:[\w-]+:\/\/)?[a...
  function a (line 1) | function a(e,t){var n=new FormData,r=new File([JSON.stringify(e)],"data....
  function s (line 1) | function s(e,t){return Q.isString(e)?e.length>ge?(ee.alert("File exceeds...
  function l (line 1) | function l(e,t,n){s(e,function(e){return!e||Q.handleImportData(e,n)?t():...
  function c (line 1) | function c(e){var t=location.hash.substring(1);return t=t?t.replace(/[?#...
  function u (line 1) | function u(e){try{var t=JSON.parse(e);return t&&"object"===("undefined"=...
  function d (line 1) | function d(e,t){var n,r=e.length;for(n=0;r>n;n++)if(-1===y.inArray(e[n],...
  function p (line 1) | function p(e){if(0==e.indexOf("{")){var t=e.lastIndexOf("}");return t>1&...
  function h (line 1) | function h(e){if(0==e.indexOf("(")){var t=e.lastIndexOf(")");return-1!=t...
  function g (line 1) | function g(e,t){if(t.length){for(var n=0,r=e.length;r>n;n++)if(Q.isGroup...
  function f (line 1) | function f(e,t,n){var r=n.getChangedList();if(r.length){var o,i,a=[];ret...
  function m (line 1) | function m(e){return"crt"===e||"pem"===e?e:"cer"}
  function e (line 1) | function e(e){if(e=e&&e.trim()){var t=e.indexOf("://")+3;if(e=-1!=t?e.su...
  function t (line 2) | function t(e,i){e=e||o.state.network,clearTimeout(a),a=null,"network"==o...
  function n (line 2) | function n(e){(e||!o.state.network.isTreeView)&&(l.scrollTop=1e7)}
  function r (line 2) | function r(e){var t=s.find(".ReactVirtualized__Grid__innerScrollContaine...
  function n (line 3) | function n(e){var t=e.length;if(t%4>0)throw new Error("Invalid string. L...
  function r (line 3) | function r(e){var t=n(e),r=t[0],o=t[1];return 3*(r+o)/4-o}
  function o (line 3) | function o(e,t,n){return 3*(t+n)/4-n}
  function i (line 3) | function i(e){var t,r,i=n(e),a=i[0],s=i[1],l=new d(o(e,a,s)),c=0,p=s>0?a...
  function a (line 3) | function a(e){return c[e>>18&63]+c[e>>12&63]+c[e>>6&63]+c[63&e]}
  function s (line 3) | function s(e,t,n){for(var r,o=[],i=t;n>i;i+=3)r=(e[i]<<16&16711680)+(e[i...
  function l (line 3) | function l(e){for(var t,n=e.length,r=n%3,o=[],i=16383,a=0,l=n-r;l>a;a+=i...
  function n (line 3) | function n(e,t){t=t||0;for(var n=Math.min(e.length,r);n>t;t++){var o=e[t...
  function r (line 7) | function r(e,t){for(var n=0;n<e.length;n++){var r=e[n],o=d[r.id];if(o){o...
  function o (line 7) | function o(e){for(var t=[],n={},r=0;r<e.length;r++){var o=e[r],i=o[0],a=...
  function i (line 7) | function i(){var e=document.createElement("style"),t=g();return e.type="...
  function a (line 7) | function a(){var e=document.createElement("link"),t=g();return e.rel="st...
  function s (line 7) | function s(e,t){var n,r,o;if(t.singleton){var s=m++;n=f||(f=i()),r=l.bin...
  function l (line 7) | function l(e,t,n,r){var o=n?"":r.css;if(e.styleSheet)e.styleSheet.cssTex...
  function c (line 7) | function c(e,t){var n=t.css,r=t.media;t.sourceMap;if(r&&e.setAttribute("...
  function u (line 7) | function u(e,t){var n=t.css,r=(t.media,t.sourceMap);r&&(n+="\n/*# source...
  function a (line 17) | function a(e){return null==e?e+"":"object"==typeof e?Ke[Ze.call(e)]||"ob...
  function s (line 17) | function s(e){return null!=e&&e===e.window}
  function l (line 17) | function l(e){var t=!!e&&e.length,n=a(e);return"function"==typeof e||s(e...
  function c (line 17) | function c(e,t,n){n=n||rt;var r,o=n.createElement("script");o.text=e;for...
  function u (line 17) | function u(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerC...
  function d (line 17) | function d(){function e(n,r){return t.push(n+" ")>st.expr.cacheLength&&d...
  function p (line 17) | function p(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}
  function h (line 17) | function h(e){return e.replace(xt,Tt)}
  function g (line 17) | function g(e){st.error("Syntax error, unrecognized expression: "+e)}
  function f (line 17) | function f(e,t){var n,r,o,i,a,s,l,c=Nt[e+" "];if(c)return t?0:c.slice(0)...
  function m (line 17) | function m(e){for(var t=0,n=e.length,r="";n>t;t++)r+=e[t].value;return r}
  function A (line 17) | function A(e,t,n,r,o,i,s){var l=0,c=e.length,u=null==n;if("object"===a(n...
  function M (line 17) | function M(e,t){return t?"\x00"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(...
  function w (line 17) | function w(e,t){if(e===t)return St=!0,0;var n=!e.compareDocumentPosition...
  function v (line 17) | function v(e,t,n,r){var o,i,a,s,l,c,u,d=t&&t.ownerDocument,h=t?t.nodeTyp...
  function b (line 17) | function b(e){return e[st.expando]=!0,e}
  function y (line 17) | function y(e){return function(t){return u(t,"input")&&t.type===e}}
  function x (line 17) | function x(e){return function(t){return(u(t,"input")||u(t,"button"))&&t....
  function T (line 17) | function T(e){return function(t){return"form"in t?t.parentNode&&t.disabl...
  function C (line 17) | function C(e){return b(function(t){return t=+t,b(function(n,r){for(var o...
  function N (line 17) | function N(e){var t,n=e?e.ownerDocument||e:rt;n!=Bt&&9===n.nodeType&&(Bt...
  function I (line 17) | function I(){}
  function E (line 17) | function E(e,t,n){var r=t.dir,o=t.next,i=o||r,a=n&&"parentNode"===i,s=Ot...
  function D (line 17) | function D(e){return e.length>1?function(t,n,r){for(var o=e.length;o--;)...
  function S (line 17) | function S(e,t,n){for(var r=0,o=t.length;o>r;r++)v(e,t[r],n);return n}
  function L (line 17) | function L(e,t,n,r,o){for(var i,a=[],s=0,l=e.length,c=null!=t;l>s;s++)(i...
  function k (line 17) | function k(e,t,n,r,o,i){return r&&!r[st.expando]&&(r=k(r)),o&&!o[st.expa...
  function j (line 17) | function j(e){for(var t,n,r,o=e.length,i=st.expr.relative[e[0].type],a=i...
  function U (line 17) | function U(e,t){var n=t.length>0,r=e.length>0,o=function(o,i,a,s,l){var ...
  function B (line 17) | function B(e,t){var n,r=[],o=[],i=Ft[e+" "];if(!i){for(t||(t=f(e)),n=t.l...
  function R (line 17) | function R(e,t,n,r){var o,i,a,s,l,c="function"==typeof e&&e,u=!r&&f(e=c....
  function z (line 17) | function z(e,t,n){for(var r=[],o=void 0!==n;(e=e[t])&&9!==e.nodeType;)if...
  function Q (line 17) | function Q(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n....
  function O (line 17) | function O(e){return"<"===e[0]&&">"===e[e.length-1]&&e.length>=3}
  function H (line 17) | function H(e,t,n){return"function"==typeof t?st.grep(e,function(e,r){ret...
  function F (line 17) | function F(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}
  function V (line 17) | function V(e){var t={};return st.each(e.match(Et)||[],function(e,n){t[n]...
  function P (line 17) | function P(e){return e}
  function Y (line 17) | function Y(e){throw e}
  function G (line 17) | function G(e,t,n,r){var o;try{e&&"function"==typeof(o=e.promise)?o.call(...
  function W (line 17) | function W(){rt.removeEventListener("DOMContentLoaded",W),n.removeEventL...
  function X (line 17) | function X(e,t){return t.toUpperCase()}
  function _ (line 17) | function _(e){return e.replace(sn,X)}
  function q (line 17) | function q(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType}
  function J (line 17) | function J(){this.expando=st.expando+J.uid++}
  function K (line 17) | function K(e){return"true"===e?!0:"false"===e?!1:"null"===e?null:e===+e+...
  function Z (line 17) | function Z(e,t,n){var r;if(void 0===n&&1===e.nodeType)if(r="data-"+t.rep...
  function $ (line 17) | function $(e,t){return e=t||e,"none"===e.style.display||""===e.style.dis...
  function ee (line 17) | function ee(e){return fn.test(e)&&mn.test(e[0].toUpperCase()+e.slice(1))}
  function te (line 17) | function te(e,t,n,r){var o,i,a=20,s=r?function(){return r.cur()}:functio...
  function ne (line 17) | function ne(e){return _(e.replace(An,"ms-"))}
  function re (line 17) | function re(e){var t,n=e.ownerDocument,r=e.nodeName,o=Mn[r];return o?o:(...
  function oe (line 17) | function oe(e,t){for(var n,r,o=[],i=0,a=e.length;a>i;i++)r=e[i],r.style&...
  function ie (line 17) | function ie(e,t){var n;return n="undefined"!=typeof e.getElementsByTagNa...
  function ae (line 17) | function ae(e,t){for(var n=0,r=e.length;r>n;n++)ln.set(e[n],"globalEval"...
  function se (line 17) | function se(e,t,n,r,o){for(var i,s,c,u,d,p,h=t.createDocumentFragment(),...
  function le (line 17) | function le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}
  function ce (line 17) | function ce(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.sli...
  function ue (line 17) | function ue(e,t,n,r){t=_e(t);var o,i,a,s,l,u,d=0,p=e.length,h=p-1,g=t[0]...
  function de (line 17) | function de(){return!0}
  function pe (line 17) | function pe(){return!1}
  function he (line 17) | function he(e,t,n,r,o,i){var a,s;if("object"==typeof t){"string"!=typeof...
  function ge (line 17) | function ge(e,t,n){return n?(ln.set(e,t,!1),void st.event.add(e,t,{names...
  function fe (line 17) | function fe(e,t){return u(e,"table")&&u(11!==t.nodeType?t:t.firstChild,"...
  function me (line 17) | function me(e,t){var n,r,o,i=ln.get(e,"events");if(1===t.nodeType){if(i)...
  function Ae (line 17) | function Ae(e,t,n){for(var r,o=t?st.filter(t,e):e,i=0;null!=(r=o[i]);i++...
  function Me (line 17) | function Me(e){var t=e.ownerDocument.defaultView;return t||(t=n),t.getCo...
  function we (line 17) | function we(e,t,n){var r,o,i={};for(o in t)i[o]=e.style[o],e.style[o]=t[...
  function ve (line 17) | function ve(e,t,n){var r,o=Ln.test(t);return n=n||Me(e),n&&(r=n.getPrope...
  function be (line 17) | function be(e){for(var t=e[0].toUpperCase()+e.slice(1),n=kn.length;n--;)...
  function ye (line 17) | function ye(e){return e in jn?e:be(e)||e}
  function xe (line 17) | function xe(){if(Un&&Un.style){var e,t=rt.createElement("col"),r=rt.crea...
  function Te (line 17) | function Te(e,t,n){var r=hn.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[...
  function Ce (line 17) | function Ce(e,t,n,r,o,i){var a="width"===t?1:0,s=0,l=0,c=0;if(n===(r?"bo...
  function Ne (line 17) | function Ne(e,t,n){var r=Me(e),o=ut||n,i=o&&"border-box"===st.css(e,"box...
  function Ie (line 17) | function Ie(e,t,n,r,o){return new Ie.prototype.init(e,t,n,r,o)}
  function Ee (line 17) | function Ee(){Qn&&(rt.hidden===!1&&n.requestAnimationFrame?n.requestAnim...
  function De (line 17) | function De(){return n.setTimeout(function(){zn=void 0}),zn=Date.now()}
  function Se (line 17) | function Se(e,t){var n,r=0,o={height:e};for(t=t?1:0;4>r;r+=2-t)n=gn[r],o...
  function Le (line 17) | function Le(e,t,n){for(var r,o=(Ue.tweeners[t]||[]).concat(Ue.tweeners["...
  function ke (line 17) | function ke(e,t,n){var r,o,i,a,s,l,c,u,d="width"in t||"height"in t,p=thi...
  function je (line 17) | function je(e,t){var n,r,o,i,a;for(n in e)if(r=ne(n),o=t[r],i=e[n],Array...
  function Ue (line 17) | function Ue(e,t,n){var r,o,i=0,a=Ue.prefilters.length,s=st.Deferred().al...
  function Be (line 17) | function Be(e){var t=e.match(Et)||[];return t.join(" ")}
  function Re (line 17) | function Re(e){return e.getAttribute&&e.getAttribute("class")||""}
  function ze (line 17) | function ze(e){return Array.isArray(e)?e:"string"==typeof e?e.match(Et)|...
  function Qe (line 17) | function Qe(e,t,n,r){var o;if(Array.isArray(t))st.each(t,function(t,o){n...
  function Oe (line 17) | function Oe(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var ...
  function He (line 17) | function He(e,t,n,r){function o(s){var l;return i[s]=!0,st.each(e[s]||[]...
  function Fe (line 17) | function Fe(e,t){var n,r,o=st.ajaxSettings.flatOptions||{};for(n in t)vo...
  function Ve (line 17) | function Ve(e,t,n){for(var r,o,i,a,s=e.contents,l=e.dataTypes;"*"===l[0]...
  function Pe (line 17) | function Pe(e,t,n,r){var o,i,a,s,l,c={},u=e.dataTypes.slice();if(u[1])fo...
  function Ye (line 17) | function Ye(e){return e.scriptAttrs||!e.headers&&(e.crossDomain||e.async...
  function i (line 18) | function i(e,t,r,o){return function(){var s=this,l=arguments,c=function(...
  function n (line 18) | function n(e){var t=st.event.fix(e);t.type="focusin"===e.type?"focus":"b...
  function r (line 19) | function r(e,t,r,s){var c,p,h,v,b,y=t;u||(u=!0,l&&n.clearTimeout(l),o=vo...
  function t (line 24) | function t(){var e=document.createElement("bootstrap"),t={WebkitTransiti...
  function t (line 24) | function t(t){return this.each(function(){var n=e(this),o=n.data("bs.ale...
  function n (line 24) | function n(){a.detach().trigger("closed.bs.alert").remove()}
  function t (line 24) | function t(t){return this.each(function(){var r=e(this),o=r.data("bs.but...
  function t (line 24) | function t(t){return this.each(function(){var r=e(this),o=r.data("bs.car...
  function t (line 24) | function t(t){var n,r=t.attr("data-target")||(n=t.attr("href"))&&n.repla...
  function n (line 24) | function n(t){return this.each(function(){var n=e(this),o=n.data("bs.col...
  function t (line 24) | function t(t){var n=t.attr("data-target");n||(n=t.attr("href"),n=n&&/#[A...
  function n (line 24) | function n(n){n&&3===n.which||(e(o).remove(),e(i).each(function(){var r=...
  function r (line 24) | function r(t){return this.each(function(){var n=e(this),r=n.data("bs.dro...
  function t (line 24) | function t(t,r){return this.each(function(){var o=e(this),i=o.data("bs.m...
  function t (line 24) | function t(t){return this.each(function(){var r=e(this),o=r.data("bs.too...
  function r (line 24) | function r(){"in"!=o.hoverState&&i.detach(),o.$element.removeAttr("aria-...
  function t (line 24) | function t(t){return this.each(function(){var r=e(this),o=r.data("bs.pop...
  function t (line 24) | function t(n,r){this.$body=e(document.body),this.$scrollElement=e(e(n).i...
  function n (line 24) | function n(n){return this.each(function(){var r=e(this),o=r.data("bs.scr...
  function t (line 25) | function t(t){return this.each(function(){var r=e(this),o=r.data("bs.tab...
  function i (line 25) | function i(){a.removeClass("active").find("> .dropdown-menu > .active")....
  function t (line 25) | function t(t){return this.each(function(){var r=e(this),o=r.data("bs.aff...
  function n (line 30) | function n(e){if(null===e||void 0===e)throw new TypeError("Object.assign...
  function r (line 30) | function r(){try{if(!Object.assign)return!1;var e=new String("abc");if(e...
  function r (line 30) | function r(e,t,n){this.props=e,this.context=t,this.refs=c,this.updater=n...
  function o (line 30) | function o(e,t,n){this.props=e,this.context=t,this.refs=c,this.updater=n...
  function i (line 30) | function i(){}
  function n (line 30) | function n(e){for(var t=arguments.length-1,n="Minified React error #"+e+...
  function r (line 30) | function r(e,t){}
  function n (line 30) | function n(e){return function(){return e}}
  function r (line 30) | function r(e,t,n,r,i,a,s,l){if(o(t),!e){var c;if(void 0===t)c=new Error(...
  function r (line 30) | function r(e){return(""+e).replace(v,"$&/")}
  function o (line 30) | function o(e,t){this.func=e,this.context=t,this.count=0}
  function i (line 30) | function i(e,t,n){var r=e.func,o=e.context;r.call(o,t,e.count++)}
  function a (line 30) | function a(e,t,n){if(null==e)return e;var r=o.getPooled(t,n);A(e,i,r),o....
  function s (line 30) | function s(e,t,n,r){this.result=e,this.keyPrefix=t,this.func=n,this.cont...
  function l (line 30) | function l(e,t,n){var o=e.result,i=e.keyPrefix,a=e.func,s=e.context,l=a....
  function c (line 30) | function c(e,t,n,o,i){var a="";null!=n&&(a=r(n)+"/");var c=s.getPooled(t...
  function u (line 30) | function u(e,t,n){if(null==e)return e;var r=[];return c(e,r,null,t,n),r}
  function d (line 30) | function d(e,t,n){return null}
  function p (line 30) | function p(e,t){return A(e,d,null)}
  function h (line 30) | function h(e){var t=[];return c(e,t,null,m.thatReturnsArgument),t}
  function r (line 30) | function r(e){return void 0!==e.ref}
  function o (line 30) | function o(e){return void 0!==e.key}
  function r (line 30) | function r(e,t){return e&&"object"==typeof e&&null!=e.key?c.escape(e.key...
  function o (line 30) | function o(e,t,n,i){var p=typeof e;if(("undefined"===p||"boolean"===p)&&...
  function i (line 30) | function i(e,t,n){return null==e?0:o(e,"",t,n)}
  function n (line 30) | function n(e){var t=e&&(r&&e[r]||e[o]);return"function"==typeof t?t:void 0}
  function n (line 30) | function n(e){var t=/[=:]/g,n={"=":"=0",":":"=2"},r=(""+e).replace(t,fun...
  function r (line 30) | function r(e){var t=/(=0|=2)/g,n={"=0":"=","=2":":"},r="."===e[0]&&"$"==...
  function r (line 30) | function r(){return null}
  function n (line 30) | function n(e){var t=e&&(k&&e[k]||e[j]);return"function"==typeof t?t:void 0}
  function u (line 30) | function u(e,t){return e===t?0!==e||1/e===1/t:e!==e&&t!==t}
  function d (line 30) | function d(e,t){this.message=e,this.data=t&&"object"==typeof t?t:{},this...
  function p (line 30) | function p(e){function n(n,r,o,i,s,l,c){if(i=i||U,l=l||o,c!==a){if(t){va...
  function h (line 30) | function h(e){function t(t,n,r,o,i,a){var s=t[n],l=E(s);if(l!==e){var c=...
  function g (line 30) | function g(){return p(r)}
  function f (line 30) | function f(e){function t(t,n,r,o,i){if("function"!=typeof e)return new d...
  function m (line 30) | function m(){function t(t,n,r,o,i){var a=t[n];if(!e(a)){var s=E(a);retur...
  function A (line 30) | function A(){function e(e,t,n,r,i){var a=e[t];if(!o.isValidElementType(a...
  function M (line 30) | function M(e){function t(t,n,r,o,i){if(!(t[n]instanceof e)){var a=e.name...
  function w (line 30) | function w(e){function t(t,n,r,o,i){for(var a=t[n],s=0;s<e.length;s++)if...
  function v (line 30) | function v(e){function t(t,n,r,o,i){if("function"!=typeof e)return new d...
  function b (line 30) | function b(e){function t(t,n,r,o,i){for(var l=[],c=0;c<e.length;c++){var...
  function y (line 30) | function y(){function e(e,t,n,r,o){return N(e[t])?null:new d("Invalid "+...
  function x (line 30) | function x(e,t,n,r,o){return new d((e||"React class")+": "+t+" type `"+n...
  function T (line 30) | function T(e){function t(t,n,r,o,i){var s=t[n],l=E(s);if("object"!==l)re...
  function C (line 30) | function C(e){function t(t,n,r,o,l){var c=t[n],u=E(c);if("object"!==u)re...
  function N (line 30) | function N(t){switch(typeof t){case"number":case"string":case"undefined"...
  function I (line 30) | function I(e,t){return"symbol"===e?!0:t?"Symbol"===t["@@toStringTag"]?!0...
  function E (line 30) | function E(e){var t=typeof e;return Array.isArray(e)?"array":e instanceo...
  function D (line 30) | function D(e){if("undefined"==typeof e||null===e)return""+e;var t=E(e);i...
  function S (line 30) | function S(e){var t=D(e);switch(t){case"array":case"object":return"an "+...
  function L (line 30) | function L(e){return e.constructor&&e.constructor.name?e.constructor.nam...
  function n (line 38) | function n(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t...
  function r (line 38) | function r(e){return n(e)===h}
  function r (line 38) | function r(e,t,n,r,o){}
  function r (line 38) | function r(e,t,n,r,o,i,a,s){if(c(t),!e){var l;if(void 0===t)l=new Error(...
  function o (line 38) | function o(e){return e}
  function i (line 38) | function i(e,t,n){function i(e,t){var n=M.hasOwnProperty(t)?M[t]:null;x....
  function r (line 38) | function r(e){return i.isValidElement(e)?void 0:o("143"),e}
  function r (line 38) | function r(e,t){return 1===e.nodeType&&e.getAttribute(g)===String(t)||8=...
  function o (line 38) | function o(e){for(var t;t=e._renderedComponent;)e=t;return e}
  function i (line 38) | function i(e,t){var n=o(e);n._hostNode=t,t[m]=n}
  function a (line 38) | function a(e){var t=e._hostNode;t&&(delete t[m],e._hostNode=null)}
  function s (line 38) | function s(e,t){if(!(e._flags&f.hasCachedChildNodes)){var n=e._renderedC...
  function l (line 38) | function l(e){if(e[m])return e[m];for(var t=[];!e[m];){if(t.push(e),!e.p...
  function c (line 38) | function c(e){var t=l(e);return null!=t&&t._hostNode===e?t:null}
  function u (line 38) | function u(e){if(void 0===e._hostNode?d("33"):void 0,e._hostNode)return ...
  function n (line 38) | function n(e){for(var t=arguments.length-1,n="Minified React error #"+e+...
  function r (line 38) | function r(e,t){return(e&t)===t}
  function r (line 38) | function r(){x||(x=!0,M.EventEmitter.injectReactEventListener(A),M.Event...
  function r (line 38) | function r(){var e=window.opera;return"object"==typeof e&&"function"==ty...
  function o (line 38) | function o(e){return(e.ctrlKey||e.altKey||e.metaKey)&&!(e.ctrlKey&&e.alt...
  function i (line 38) | function i(e){switch(e){case"topCompositionStart":return N.compositionSt...
  function a (line 38) | function a(e,t){return"topKeyDown"===e&&t.keyCode===w}
  function s (line 38) | function s(e,t){switch(e){case"topKeyUp":return-1!==M.indexOf(t.keyCode)...
  function l (line 38) | function l(e){var t=e.detail;return"object"==typeof t&&"data"in t?t.data...
  function c (line 38) | function c(e,t,n,r){var o,c;if(v?o=i(e):E?s(e,n)&&(o=N.compositionEnd):a...
  function u (line 38) | function u(e,t){switch(e){case"topCompositionEnd":return l(t);case"topKe...
  function d (line 38) | function d(e,t){if(E){if("topCompositionEnd"===e||!v&&s(e,t)){var n=E.ge...
  function p (line 38) | function p(e,t,n,r){var o;if(o=y?u(e,n):d(e,n),!o)return null;var i=A.ge...
  function r (line 38) | function r(e,t,n){var r=t.dispatchConfig.phasedRegistrationNames[n];retu...
  function o (line 38) | function o(e,t,n){var o=r(e,n,t);o&&(n._dispatchListeners=f(n._dispatchL...
  function i (line 38) | function i(e){e&&e.dispatchConfig.phasedRegistrationNames&&g.traverseTwo...
  function a (line 38) | function a(e){if(e&&e.dispatchConfig.phasedRegistrationNames){var t=e._t...
  function s (line 38) | function s(e,t,n){if(n&&n.dispatchConfig.registrationName){var r=n.dispa...
  function l (line 38) | function l(e){e&&e.dispatchConfig.registrationName&&s(e._targetInst,null...
  function c (line 38) | function c(e){m(e,i)}
  function u (line 38) | function u(e){m(e,a)}
  function d (line 38) | function d(e,t,n,r){g.traverseEnterLeave(n,r,s,e,t)}
  function p (line 38) | function p(e){m(e,l)}
  function r (line 38) | function r(e){return"button"===e||"input"===e||"select"===e||"textarea"=...
  function o (line 38) | function o(e,t,n){switch(e){case"onClick":case"onClickCapture":case"onDo...
  function r (line 38) | function r(){if(s)for(var e in l){var t=l[e],n=s.indexOf(e);if(n>-1?void...
  function o (line 38) | function o(e,t,n){c.eventNameDispatchConfigs.hasOwnProperty(n)?a("99",n)...
  function i (line 38) | function i(e,t,n){c.registrationNameModules[e]?a("100",e):void 0,c.regis...
  function r (line 38) | function r(e){return"topMouseUp"===e||"topTouchEnd"===e||"topTouchCancel...
  function o (line 38) | function o(e){return"topMouseMove"===e||"topTouchMove"===e}
  function i (line 38) | function i(e){return"topMouseDown"===e||"topTouchStart"===e}
  function a (line 38) | function a(e,t,n,r){var o=e.type||"unknown-event";e.currentTarget=A.getN...
  function s (line 38) | function s(e,t){var n=e._dispatchListeners,r=e._dispatchInstances;if(Arr...
  function l (line 38) | function l(e){var t=e._dispatchListeners,n=e._dispatchInstances;if(Array...
  function c (line 38) | function c(e){var t=l(e);return e._dispatchInstances=null,e._dispatchLis...
  function u (line 38) | function u(e){var t=e._dispatchListeners,n=e._dispatchInstances;Array.is...
  function d (line 38) | function d(e){return!!e._dispatchListeners}
  function r (line 38) | function r(e,t,n){try{t(n)}catch(r){null===o&&(o=r)}}
  function r (line 38) | function r(e,t){return null==t?o("30"):void 0,null==e?t:Array.isArray(e)...
  function n (line 38) | function n(e,t,n){Array.isArray(e)?e.forEach(t,n):e&&t.call(n,e)}
  function r (line 38) | function r(e){this._root=e,this._startText=this.getText(),this._fallback...
  function r (line 38) | function r(){return!i&&o.canUseDOM&&(i="textContent"in document.document...
  function r (line 38) | function r(e,t,n,r){return o.call(this,e,t,n,r)}
  function r (line 38) | function r(e,t,n,r){this.dispatchConfig=e,this._targetInst=t,this.native...
  function r (line 38) | function r(e,t,n,r){return o.call(this,e,t,n,r)}
  function r (line 38) | function r(e,t,n){var r=N.getPooled(L.change,e,t,n);return r.type="chang...
  function o (line 38) | function o(e){var t=e.nodeName&&e.nodeName.toLowerCase();return"select"=...
  function i (line 38) | function i(e){var t=r(j,e,E(e));C.batchedUpdates(a,t)}
  function a (line 38) | function a(e){b.enqueueEvents(e),b.processEventQueue(!1)}
  function s (line 38) | function s(e,t){k=e,j=t,k.attachEvent("onchange",i)}
  function l (line 38) | function l(){k&&(k.detachEvent("onchange",i),k=null,j=null)}
  function c (line 38) | function c(e,t){var n=I.updateValueIfChanged(e),r=t.simulated===!0&&R._a...
  function u (line 38) | function u(e,t){return"topChange"===e?t:void 0}
  function d (line 38) | function d(e,t,n){"topFocus"===e?(l(),s(t,n)):"topBlur"===e&&l()}
  function p (line 38) | function p(e,t){k=e,j=t,k.attachEvent("onpropertychange",g)}
  function h (line 38) | function h(){k&&(k.detachEvent("onpropertychange",g),k=null,j=null)}
  function g (line 38) | function g(e){"value"===e.propertyName&&c(j,e)&&i(e)}
  function f (line 38) | function f(e,t,n){"topFocus"===e?(h(),p(t,n)):"topBlur"===e&&h()}
  function m (line 38) | function m(e,t,n){return"topSelectionChange"===e||"topKeyUp"===e||"topKe...
  function A (line 38) | function A(e){var t=e.nodeName;return t&&"input"===t.toLowerCase()&&("ch...
  function M (line 38) | function M(e,t,n){return"topClick"===e?c(t,n):void 0}
  function w (line 38) | function w(e,t,n){return"topInput"===e||"topChange"===e?c(t,n):void 0}
  function v (line 38) | function v(e,t){if(null!=e){var n=e._wrapperState||t._wrapperState;if(n&...
  function r (line 38) | function r(){E.ReactReconcileTransaction&&y?void 0:u("123")}
  function o (line 38) | function o(){this.reinitializeTransaction(),this.dirtyComponentsLength=n...
  function i (line 38) | function i(e,t,n,o,i,a){return r(),y.batchedUpdates(e,t,n,o,i,a)}
  function a (line 38) | function a(e,t){return e._mountOrder-t._mountOrder}
  function s (line 38) | function s(e){var t=e.dirtyComponentsLength;t!==M.length?u("124",t,M.len...
  function l (line 38) | function l(e){return r(),y.isBatchingUpdates?(M.push(e),void(null==e._up...
  function c (line 38) | function c(e,t){A(y.isBatchingUpdates,"ReactUpdates.asap: Can't enqueue ...
  function r (line 39) | function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a ...
  function e (line 39) | function e(t){r(this,e),this._callbacks=null,this._contexts=null,this._a...
  function r (line 39) | function r(){o.attachRefs(this,this._currentElement)}
  function r (line 39) | function r(e,t,n){"function"==typeof e?e(t.getPublicInstance()):i.addCom...
  function o (line 39) | function o(e,t,n){"function"==typeof e?e(null):i.removeComponentAsRefFro...
  function r (line 39) | function r(e){return!(!e||"function"!=typeof e.attachRef||"function"!=ty...
  function r (line 39) | function r(e){var t=e.type,n=e.nodeName;return n&&"input"===n.toLowerCas...
  function o (line 39) | function o(e){return e._wrapperState.valueTracker}
  function i (line 39) | function i(e,t){e._wrapperState.valueTracker=t}
  function a (line 39) | function a(e){e._wrapperState.valueTracker=null}
  function s (line 39) | function s(e){var t;return e&&(t=r(e)?""+e.checked:e.value),t}
  function n (line 39) | function n(e){var t=e.target||e.srcElement||window;return t.correspondin...
  function r (line 53) | function r(e,t){if(!i.canUseDOM||t&&!("addEventListener"in document))ret...
  function n (line 53) | function n(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return"input...
  function r (line 53) | function r(e,t,n,r){return o.call(this,e,t,n,r)}
  function r (line 53) | function r(e,t,n,r){return o.call(this,e,t,n,r)}
  function n (line 53) | function n(e){var t=this,n=t.nativeEvent;if(n.getModifierState)return n....
  function r (line 53) | function r(e){return n}
  function r (line 53) | function r(e,t){return Array.isArray(t)&&(t=t[1]),t?t.nextSibling:e.firs...
  function o (line 53) | function o(e,t,n){u.insertTreeBefore(e,t,n)}
  function i (line 53) | function i(e,t,n){Array.isArray(t)?s(e,t[0],t[1],n):f(e,t,n)}
  function a (line 53) | function a(e,t){if(Array.isArray(t)){var n=t[1];t=t[0],l(e,t,n),e.remove...
  function s (line 53) | function s(e,t,n,r){for(var o=t;;){var i=o.nextSibling;if(f(e,o,r),o===n...
  function l (line 53) | function l(e,t,n){for(;;){var r=t.nextSibling;if(r===n)break;e.removeChi...
  function c (line 53) | function c(e,t,n){var r=e.parentNode,o=e.nextSibling;o===t?n&&f(r,docume...
  function r (line 53) | function r(e){if(m){var t=e.node,n=e.children;if(n.length)for(var r=0;r<...
  function o (line 53) | function o(e,t){e.parentNode.replaceChild(t.node,e),r(t)}
  function i (line 53) | function i(e,t){m?e.children.push(t):e.node.appendChild(t.node)}
  function a (line 53) | function a(e,t){m?e.html=t:d(e.node,t)}
  function s (line 53) | function s(e,t){m?e.text=t:h(e.node,t)}
  function l (line 53) | function l(){return this.node.nodeName}
  function c (line 53) | function c(e){return{node:e,children:[],html:null,text:null,toString:l}}
  function n (line 53) | function n(e){var t=""+e,n=o.exec(t);if(!n)return t;var r,i="",a=0,s=0;f...
  function r (line 53) | function r(e){return"boolean"==typeof e||"number"==typeof e?""+e:n(e)}
  function r (line 53) | function r(e){var t=e.match(u);return t&&t[1].toLowerCase()}
  function o (line 53) | function o(e,t){var n=c;c?void 0:l(!1);var o=r(e),i=o&&s(o);if(i){n.inne...
  function r (line 53) | function r(e){var t=e.length;if(Array.isArray(e)||"object"!=typeof e&&"f...
  function o (line 53) | function o(e){return!!e&&("object"==typeof e||"function"==typeof e)&&"le...
  function i (line 53) | function i(e){return o(e)?Array.isArray(e)?e.slice():r(e):[e]}
  function r (line 53) | function r(e){return a?void 0:i(!1),p.hasOwnProperty(e)||(e="*"),s.hasOw...
  function r (line 53) | function r(e){if(e){var t=e._currentElement._owner||null;if(t){var n=t.g...
  function o (line 53) | function o(e,t){t&&(J[e._tag]&&(null!=t.children||null!=t.dangerouslySet...
  function i (line 53) | function i(e,t,n,r){if(!(r instanceof U)){var o=e._hostContainerInfo,i=o...
  function a (line 53) | function a(){var e=this;T.putListener(e.inst,e.registrationName,e.listen...
  function s (line 53) | function s(){var e=this;D.postMountWrapper(e)}
  function l (line 53) | function l(){var e=this;k.postMountWrapper(e)}
  function c (line 53) | function c(){var e=this;S.postMountWrapper(e)}
  function u (line 53) | function u(){R.track(this)}
  function d (line 53) | function d(){var e=this;e._rootNodeID?void 0:m("63");var t=O(e);switch(t...
  function p (line 53) | function p(){L.postUpdateWrapper(this)}
  function h (line 53) | function h(e){$.call(Z,e)||(K.test(e)?void 0:m("65",e),Z[e]=!0)}
  function g (line 53) | function g(e,t){return e.indexOf("-")>=0||null!=t.is}
  function f (line 53) | function f(e){var t=e.type;h(t),this._currentElement=e,this._tag=t.toLow...
  function n (line 53) | function n(e){try{e.focus()}catch(t){}}
  function n (line 53) | function n(e,t){return e+t.charAt(0).toUpperCase()+t.substring(1)}
  function r (line 53) | function r(e){return o(e.replace(i,"ms-"))}
  function n (line 53) | function n(e){return e.replace(r,function(e,t){return t.toUpperCase()})}
  function r (line 53) | function r(e,t,n,r){var o=null==t||"boolean"==typeof t||""===t;if(o)retu...
  function r (line 53) | function r(e){return o(e).replace(i,"-ms-")}
  function n (line 53) | function n(e){return e.replace(r,"-$1").toLowerCase()}
  function n (line 53) | function n(e){var t={};return function(n){return t.hasOwnProperty(n)||(t...
  function r (line 53) | function r(e){return c.hasOwnProperty(e)?!0:l.hasOwnProperty(e)?!1:s.tes...
  function o (line 53) | function o(e,t){return null==t||e.hasBooleanValue&&!t||e.hasNumericValue...
  function r (line 53) | function r(e){return'"'+o(e)+'"'}
  function r (line 53) | function r(e){return Object.prototype.hasOwnProperty.call(e,f)||(e[f]=h+...
  function r (line 53) | function r(e){o.enqueueEvents(e),o.processEventQueue(!1)}
  function r (line 53) | function r(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["We...
  function o (line 54) | function o(e){if(s[e])return s[e];if(!a[e])return e;var t=a[e];for(var n...
  function r (line 54) | function r(){this._rootNodeID&&p.updateWrapper(this)}
  function o (line 54) | function o(e){var t="checkbox"===e.type||"radio"===e.type;return t?null!...
  function i (line 54) | function i(e){var t=this._currentElement.props,n=c.executeOnChange(t,e);...
  function r (line 54) | function r(e){null!=e.checkedLink&&null!=e.valueLink?s("87"):void 0}
  function o (line 54) | function o(e){r(e),null!=e.value||null!=e.onChange?s("88"):void 0}
  function i (line 54) | function i(e){r(e),null!=e.checked||null!=e.onChange?s("89"):void 0}
  function a (line 54) | function a(e){if(e){var t=e.getName();if(t)return" Check the render meth...
  function r (line 54) | function r(e){var t="";return i.Children.forEach(e,function(e){null!=e&&...
  function r (line 54) | function r(){if(this._rootNodeID&&this._wrapperState.pendingUpdate){this...
  function o (line 54) | function o(e,t,n){var r,o,i=l.getNodeFromInstance(e).options;if(t){for(r...
  function i (line 54) | function i(e){var t=this._currentElement.props,n=s.executeOnChange(t,e);...
  function r (line 54) | function r(){this._rootNodeID&&u.updateWrapper(this)}
  function o (line 54) | function o(e){var t=this._currentElement.props,n=s.executeOnChange(t,e);...
  function r (line 54) | function r(e,t,n){return{type:"INSERT_MARKUP",content:e,fromIndex:null,f...
  function o (line 54) | function o(e,t,n){return{type:"MOVE_EXISTING",content:null,fromIndex:e._...
  function i (line 54) | function i(e,t){return{type:"REMOVE_NODE",content:null,fromIndex:e._moun...
  function a (line 54) | function a(e){return{type:"SET_MARKUP",content:e,fromIndex:null,fromNode...
  function s (line 54) | function s(e){return{type:"TEXT_CONTENT",content:e,fromIndex:null,fromNo...
  function l (line 54) | function l(e,t){return t&&(e=e||[],e.push(t)),e}
  function c (line 54) | function c(e,t){d.processChildrenUpdates(e,t)}
  function r (line 54) | function r(e,t,n,r){var o=void 0===e[n];null!=t&&o&&(e[n]=i(t,!0))}
  function n (line 54) | function n(){throw new Error("setTimeout has not been defined")}
  function r (line 54) | function r(){throw new Error("clearTimeout has not been defined")}
  function o (line 54) | function o(e){if(u===setTimeout)return setTimeout(e,0);if((u===n||!u)&&s...
  function i (line 54) | function i(e){if(d===clearTimeout)return clearTimeout(e);if((d===r||!d)&...
  function a (line 54) | function a(){f&&h&&(f=!1,h.length?g=h.concat(g):m=-1,g.length&&s())}
  function s (line 54) | function s(){if(!f){var e=o(a);f=!0;for(var t=g.length;t;){for(h=g,g=[];...
  function l (line 54) | function l(e,t){this.fun=e,this.array=t}
  function c (line 54) | function c(){}
  function r (line 54) | function r(e){if(e){var t=e.getName();if(t)return" Check the render meth...
  function o (line 54) | function o(e){return"function"==typeof e&&"undefined"!=typeof e.prototyp...
  function i (line 54) | function i(e,t){var n;if(null===e||e===!1)n=c.create(i);else if("object"...
  function r (line 54) | function r(e){}
  function o (line 54) | function o(e,t){}
  function i (line 54) | function i(e){return!(!e.prototype||!e.prototype.isReactComponent)}
  function a (line 54) | function a(e){return!(!e.prototype||!e.prototype.isPureReactComponent)}
  function n (line 54) | function n(e,t){return e===t?0!==e||0!==t||1/e===1/t:e!==e&&t!==t}
  function r (line 54) | function r(e,t){if(n(e,t))return!0;if("object"!=typeof e||null===e||"obj...
  function n (line 54) | function n(e,t){var n=null===e||e===!1,r=null===t||t===!1;if(n||r)return...
  function r (line 54) | function r(e){return s?void 0:a("111",e.type),new s(e)}
  function o (line 54) | function o(e){return new l(e)}
  function i (line 54) | function i(e){return e instanceof l}
  function n (line 54) | function n(){return r++}
  function n (line 54) | function n(e){var t=/[=:]/g,n={"=":"=0",":":"=2"},r=(""+e).replace(t,fun...
  function r (line 54) | function r(e){var t=/(=0|=2)/g,n={"=0":"=","=2":":"},r="."===e[0]&&"$"==...
  function r (line 54) | function r(e,t){return e&&"object"==typeof e&&null!=e.key?c.escape(e.key...
  function o (line 54) | function o(e,t,n,i){var p=typeof e;if(("undefined"===p||"boolean"===p)&&...
  function i (line 54) | function i(e,t,n){return null==e?0:o(e,"",t,n)}
  function n (line 54) | function n(e){var t=e&&(r&&e[r]||e[o]);return"function"==typeof t?t:void 0}
  function r (line 54) | function r(e){var t=Function.prototype.toString,n=Object.prototype.hasOw...
  function o (line 54) | function o(e){var t=c(e);if(t){var n=t.childIDs;u(e),n.forEach(o)}}
  function i (line 54) | function i(e,t,n){return"\n    in "+(e||"Unknown")+(t?" (at "+t.fileName...
  function a (line 54) | function a(e){return null==e?"#empty":"string"==typeof e||"number"==type...
  function s (line 54) | function s(e){var t,n=C.getDisplayName(e),r=C.getElement(e),o=C.getOwner...
  function r (line 54) | function r(e,t,n,r){if(e&&"object"==typeof e){var o=e,i=void 0===o[n];i&...
  function o (line 54) | function o(e,t){if(null==e)return e;var n={};return i(e,r,n),n}
  function r (line 54) | function r(e){this.reinitializeTransaction(),this.renderToStaticMarkup=e...
  function r (line 54) | function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a ...
  function o (line 54) | function o(e,t){}
  function e (line 54) | function e(t){r(this,e),this.transaction=t}
  function r (line 54) | function r(e){l.enqueueUpdate(e)}
  function o (line 54) | function o(e){var t=typeof e;if("object"!==t)return t;var n=e.constructo...
  function i (line 54) | function i(e,t){var n=s.get(e);if(!n){return null}return n}
  function r (line 55) | function r(e,t){"_hostNode"in e?void 0:l("33"),"_hostNode"in t?void 0:l(...
  function o (line 55) | function o(e,t){"_hostNode"in e?void 0:l("35"),"_hostNode"in t?void 0:l(...
  function i (line 55) | function i(e){return"_hostNode"in e?void 0:l("36"),e._hostParent}
  function a (line 55) | function a(e,t,n){for(var r=[];e;)r.push(e),e=e._hostParent;var o;for(o=...
  function s (line 55) | function s(e,t,n,o,i){for(var a=e&&t?r(e,t):null,s=[];e&&e!==a;)s.push(e...
  function r (line 55) | function r(){this.reinitializeTransaction()}
  function r (line 55) | function r(e){for(;e._hostParent;)e=e._hostParent;var t=d.getNodeFromIns...
  function o (line 55) | function o(e,t){this.topLevelType=e,this.nativeEvent=t,this.ancestors=[]}
  function i (line 55) | function i(e){var t=h(e.nativeEvent),n=d.getClosestInstanceFromNode(t),o...
  function a (line 55) | function a(e){var t=g(window);e(t)}
  function n (line 55) | function n(e){return e.Window&&e instanceof e.Window?{x:e.pageXOffset||e...
  function r (line 55) | function r(e){this.reinitializeTransaction(),this.renderToStaticMarkup=!...
  function r (line 55) | function r(e){return i(document.documentElement,e)}
  function r (line 55) | function r(e,t,n,r){return e===n&&t===r}
  function o (line 55) | function o(e){var t=document.selection,n=t.createRange(),r=n.text.length...
  function i (line 55) | function i(e){var t=window.getSelection&&window.getSelection();if(!t||0=...
  function a (line 55) | function a(e,t){var n,r,o=document.selection.createRange().duplicate();v...
  function s (line 55) | function s(e,t){if(window.getSelection){var n=window.getSelection(),r=e[...
  function n (line 55) | function n(e){for(;e&&e.firstChild;)e=e.firstChild;return e}
  function r (line 55) | function r(e){for(;e;){if(e.nextSibling)return e.nextSibling;e=e.parentN...
  function o (line 55) | function o(e,t){for(var o=n(e),i=0,a=0;o;){if(3===o.nodeType){if(a=i+o.t...
  function r (line 55) | function r(e,t){return e&&t?e===t?!0:o(e)?!1:o(t)?r(e,t.parentNode):"con...
  function r (line 55) | function r(e){return o(e)&&3==e.nodeType}
  function n (line 55) | function n(e){var t=e?e.ownerDocument||e:document,n=t.defaultView||windo...
  function n (line 55) | function n(e){if(e=e||("undefined"!=typeof document?document:void 0),"un...
  function r (line 55) | function r(e){if("selectionStart"in e&&l.hasSelectionCapabilities(e))ret...
  function o (line 55) | function o(e,t){if(M||null==f||f!==u())return null;var n=r(f);if(!A||!p(...
  function r (line 55) | function r(e){return"."+e._rootNodeID}
  function o (line 55) | function o(e){return"button"===e||"input"===e||"select"===e||"textarea"=...
  function r (line 55) | function r(e,t,n,r){return o.call(this,e,t,n,r)}
  function r (line 55) | function r(e,t,n,r){return o.call(this,e,t,n,r)}
  function r (line 55) | function r(e,t,n,r){return o.call(this,e,t,n,r)}
  function r (line 55) | function r(e,t,n,r){return o.call(this,e,t,n,r)}
  function n (line 55) | function n(e){var t,n=e.keyCode;return"charCode"in e?(t=e.charCode,0===t...
  function r (line 55) | function r(e){if(e.key){var t=i[e.key]||e.key;if("Unidentified"!==t)retu...
  function r (line 55) | function r(e,t,n,r){return o.call(this,e,t,n,r)}
  function r (line 55) | function r(e,t,n,r){return o.call(this,e,t,n,r)}
  function r (line 55) | function r(e,t,n,r){return o.call(this,e,t,n,r)}
  function r (line 55) | function r(e,t,n,r){return o.call(this,e,t,n,r)}
  function r (line 55) | function r(e,t){for(var n=Math.min(e.length,t.length),r=0;n>r;r++)if(e.c...
  function o (line 55) | function o(e){return e?e.nodeType===U?e.documentElement:e.firstChild:null}
  function i (line 55) | function i(e){return e.getAttribute&&e.getAttribute(L)||""}
  function a (line 55) | function a(e,t,n,r,o){var i;if(b.logTopLevelRenders){var a=e._currentEle...
  function s (line 55) | function s(e,t,n,r){var o=N.ReactReconcileTransaction.getPooled(!n&&v.us...
  function l (line 55) | function l(e,t,n){for(T.unmountComponent(e,n),t.nodeType===U&&(t=t.docum...
  function c (line 55) | function c(e){var t=o(e);if(t){var n=M.getInstanceFromNode(t);return!(!n...
  function u (line 55) | function u(e){return!(!e||e.nodeType!==j&&e.nodeType!==U&&e.nodeType!==B)}
  function d (line 55) | function d(e){var t=o(e),n=t&&M.getInstanceFromNode(t);return n&&!n._hos...
  function p (line 55) | function p(e){var t=d(e);return t?t._hostContainerInfo._topLevelWrapper:...
  function r (line 55) | function r(e,t){var n={_topLevelWrapper:e,_idCounter:1,_ownerDocument:t?...
  function n (line 55) | function n(e){for(var t=1,n=0,o=0,i=e.length,a=-4&i;a>o;){for(var s=Math...
  function r (line 55) | function r(e){if(null==e)return null;if(1===e.nodeType)return e;var t=a....
  function r (line 55) | function r(e){for(var t;(t=e._renderedNodeType)===o.COMPOSITE;)e=e._rend...
  function e (line 61) | function e(r){if(n[r])return n[r].exports;var o=n[r]={exports:{}};return...
  function r (line 61) | function r(e){try{return document.execCommand(e)}catch(t){return!1}}
  function o (line 61) | function o(e){var t="rtl"===document.documentElement.getAttribute("dir")...
  function i (line 61) | function i(e){"@babel/helpers - typeof";return(i="function"==typeof Symb...
  function a (line 61) | function a(e){"@babel/helpers - typeof";return(a="function"==typeof Symb...
  function s (line 61) | function s(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a ...
  function l (line 61) | function l(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.en...
  function c (line 61) | function c(e,t,n){return t&&l(e.prototype,t),n&&l(e,n),e}
  function u (line 61) | function u(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("S...
  function d (line 61) | function d(e,t){return(d=Object.setPrototypeOf||function(e,t){return e._...
  function p (line 61) | function p(e){var t=f();return function(){var n,r=m(e);if(t){var o=m(thi...
  function h (line 61) | function h(e,t){return!t||"object"!==a(t)&&"function"!=typeof t?g(e):t}
  function g (line 61) | function g(e){if(void 0===e)throw new ReferenceError("this hasn't been i...
  function f (line 61) | function f(){if("undefined"==typeof Reflect||!Reflect.construct)return!1...
  function m (line 61) | function m(e){return(m=Object.setPrototypeOf?Object.getPrototypeOf:funct...
  function A (line 61) | function A(e,t){var n="data-clipboard-".concat(e);if(t.hasAttribute(n))r...
  function t (line 61) | function t(e,r){var o;return s(this,t),o=n.call(this),o.resolveOptions(r...
  function t (line 61) | function t(e,t){for(;e&&e.nodeType!==n;){if("function"==typeof e.matches...
  function r (line 61) | function r(e,t,n,r,o){var a=i.apply(this,arguments);return e.addEventLis...
  function o (line 61) | function o(e,t,n,o,i){return"function"==typeof e.addEventListener?r.appl...
  function i (line 61) | function i(e,t,n,r){return function(n){n.delegateTarget=a(n.target,t),n....
  function r (line 61) | function r(e,t,n){if(!e&&!t&&!n)throw new Error("Missing required argume...
  function o (line 61) | function o(e,t,n){return e.addEventListener(t,n),{destroy:function(){e.r...
  function i (line 61) | function i(e,t,n){return Array.prototype.forEach.call(e,function(e){e.ad...
  function a (line 61) | function a(e,t,n){return l(document.body,e,t,n)}
  function t (line 61) | function t(e){var t;if("SELECT"===e.nodeName)e.focus(),t=e.value;else if...
  function t (line 61) | function t(){}
  function r (line 61) | function r(){o.off(e,r),t.apply(n,arguments)}
  function r (line 61) | function r(e,t){return"blank"===e?t(""):void l.getTempFile({filename:e},...
  function r (line 61) | function r(e){var n=e.enabledCount||0;t.backRulesFirst=e.backRulesFirst,...
  function o (line 61) | function o(e){return e!==ae?!1:e?e.url!==ae.url||e.ip!==ae.ip?!1:e.name=...
  function i (line 61) | function i(e){var n,r=location.hash.substring(1),i=r.indexOf("?");if(-1!...
  function a (line 61) | function a(e){e=e||{},be.set("filterText",JSON.stringify({disabledFilter...
  function s (line 61) | function s(){var e=we.parseJSON(be.get("filterText"));return e?{disabled...
  function l (line 61) | function l(e){e=e||{},be.set("networkColumns",JSON.stringify({columns:e....
  function c (line 61) | function c(){return we.parseJSON(be.get("networkColumns"))||{}}
  function u (line 61) | function u(e){var t=ft.length,n=t?we.findArray(ft,function(t){return t.t...
  function d (line 61) | function d(e){if(e=e&&e.trim()){var t=u(e);if(t)return t;var n;return e....
  function p (line 61) | function p(e,t,n){if(!e)return!1;var r;if(t.pattern)r=t.pattern.test(e);...
  function h (line 61) | function h(e,t){for(var n=0,r=t.length;r>n;n++){var o=t[n];switch(o.type...
  function g (line 61) | function g(e){return String(null==e?"":e).trim().toLowerCase()}
  function f (line 61) | function f(e){return Me({_:{url:"cgi-bin/composer",mode:e?"cancel":null}...
  function m (line 61) | function m(e,t,n,r){return"string"!=typeof e&&(e=JSON.stringify(e)),r(e,...
  function A (line 61) | function A(e){var t=++Ct;return clearTimeout(xt),xt=null,Tt(function(n){...
  function M (line 61) | function M(e){t.hasInvalidCerts!=e.hasInvalidCerts&&(t.hasInvalidCerts=e...
  function w (line 61) | function w(e){return ct[e]}
  function v (line 61) | function v(e,n){return t.getComposeData({ids:e.join()},n)}
  function b (line 61) | function b(e){var t=e&&e.length;if(t?(e=e.filter(w),t=e.length):(e=Objec...
  function y (line 61) | function y(e,t,n){if(!e[n]||ee.clientId===e[t])return!1;var r=e[t],o=e[n...
  function x (line 61) | function x(e){y(e,"mrulesClientId","mrulesTime")&&ye.trigger("rulesChang...
  function T (line 61) | function T(e){y(e,"mvaluesClientId","mvaluesTime")&&ye.trigger("valuesCh...
  function C (line 61) | function C(e,t,n){for(var r=0;n>r;r++){var o=e[r],i=t[r];if(o.name!==i.n...
  function N (line 61) | function N(e,t){var n=e.length;if(n!==t.length)return!0;for(var r=0;n>r;...
  function I (line 61) | function I(e,t,n){var r=e.length,o=t.length;return r?1===r?void((!o||o>1...
  function E (line 61) | function E(e){if(!e)return 0;var t=e.length;return"="===e[t-1]&&(t-=2,"=...
  function D (line 61) | function D(e,t){Object.keys(t).forEach(function(n){var r=t[n];if("rules"...
  function S (line 61) | function S(e){var t=[""];return e.requestTime||(t[0]=E(e.req.base64)),e....
  function L (line 61) | function L(){var e=document.querySelector("#whistleComposerFrames");retu...
  function k (line 61) | function k(){function e(){if(document.hidden){if(Date.now()-Et>Ke)return...
  function j (line 61) | function j(e,t){if(e&&t){var n={};return Object.keys(e).forEach(function...
  function U (line 61) | function U(){return de+"/"+lt++}
  function B (line 61) | function B(e){if(!e)return!1;if(e.useFrames)return!0;if(e.reqError||e.re...
  function R (line 61) | function R(e){var t=e.indexOf("&");return-1!==t&&(e=e.substring(0,t)),t=...
  function z (line 61) | function z(e,t){var n=e.lastIndexOf("&custom"+(t?"1=":"2="));if(-1!==n){...
  function Q (line 61) | function Q(e){e.style=void 0;var n=e.rules&&e.rules.style;if(n=n&&n.list...
  function O (line 61) | function O(e){var t=e&&(St.exec(e)||Lt.exec(e));if(!t){if(e){if(/\b(?:ch...
  function H (line 61) | function H(e){if(e.fc)return void(e.appName="whistle");var t=e.appName;t...
  function F (line 61) | function F(e){var t=e&&Object.keys(e);if(t&&t.length)for(var n=0,r=t.len...
  function V (line 61) | function V(e){var t=e.url,n=e.req,r=e.res;e.method=n.method;var o=e.endT...
  function P (line 61) | function P(e){var t=e&&e.url;return t&&"string"==typeof t&&-1===t.indexO...
  function Y (line 61) | function Y(){return ze.length-ve.MAX_COUNT-1}
  function G (line 61) | function G(){return le?Y()>0||t.stopRefresh?-1:oe||"0":se?-2:""}
  function W (line 61) | function W(e){return je.length?(e=e&&e.server)?(qe=0,t.setServerInfo&&t....
  function X (line 62) | function X(e){return he||et[e.slice(0,-1)]}
  function _ (line 62) | function _(e){var t=pe&&pe[e];return Array.isArray(t)||(t=[]),he?t:(Obje...
  function q (line 62) | function q(e){return"string"==typeof e?e:JSON.stringify(e)}
  function J (line 62) | function J(e,n){var r=e&&e.whistleId,o=e&&e.hasWhistleToken;if(!o!=!t.ha...
  function K (line 62) | function K(e){var t=e&&e.whistleId;J(e,!0),t&&ut!==e.rulesMFlag&&(ut=e.r...
  function r (line 62) | function r(e,t){function n(l,c,u){var d={url:"function"==typeof e?e():e}...
  function o (line 62) | function o(e,t){var n={};return Object.keys(e).forEach(function(o){n[o]=...
  function r (line 62) | function r(e){if("0"==e)return!0;if(!Wt.test(e))return!1;var t="-"===Reg...
  function o (line 62) | function o(e){return"\\r"===e?"\r":"\n"}
  function i (line 62) | function i(e){return e}
  function a (line 62) | function a(e){return e?"/"===e[0]?e:"/"+e:"/"}
  function s (line 62) | function s(e,t){if(e&&t){try{var n=e.__whistleServiceApi;n||"function"!=...
  function l (line 62) | function l(e){return e&&Pt.test(e)}
  function c (line 62) | function c(e,t){return e==t?0:e>t?-1:1}
  function u (line 62) | function u(e,t){return c(e.priority,t.priority)||c(t.mtime,e.mtime)||(e....
  function d (line 62) | function d(e){return function(t,n){var r=e[t],o=e[n];return r._key=t,o._...
  function p (line 62) | function p(e){return"string"==typeof e}
  function h (line 62) | function h(e){return p(e)?e:""}
  function g (line 62) | function g(e){return e&&"string"==typeof e}
  function f (line 62) | function f(e){return"boolean"==typeof e}
  function m (line 62) | function m(e,t){t?setTimeout(function(){xt.trigger("showService",e)},100...
  function A (line 62) | function A(e,t){try{for(var n=window.getSelection(),r=0,o=n.rangeCount;o...
  function M (line 62) | function M(){mt=gt=ft=null,xt.trigger("stopDrag")}
  function w (line 62) | function w(e,t){if(e&&"function"==typeof t&&"string"==typeof e&&(e=e.tri...
  function v (line 62) | function v(e,t){var n=Rt[e];if(n){if("function"==typeof t){var r=wt.inAr...
  function b (line 62) | function b(e,t,n){if(e&&(t||""!==t)){"string"==typeof t&&(t=t.split(".")...
  function y (line 62) | function y(e){var t=e.hostIp;if(!t)return e.serverIp;if(e.realIp)e.serve...
  function x (line 62) | function x(e,t,n){return n=n||t.name,"hostIp"===n?y(e):t.key?b(e,t.key):...
  function T (line 62) | function T(e){return!(!e||"false"===e)}
  function C (line 62) | function C(e,t){e=e||{};var n=e.status,r=t?Ct.error:Nt.alert;if(!n)retur...
  function N (line 62) | function N(e){return e&&"string"!=typeof e&&(e=e["content-type"]||e.cont...
  function I (line 62) | function I(e){if(e=N(e)){if(-1!=e.indexOf("javascript"))return"JS";if(-1...
  function E (line 62) | function E(e){return e?(e=I(e),e&&"IMG"!==e):!0}
  function D (line 62) | function D(e){if(!e)return"";var t=e.indexOf("://");t=-1==t?0:t+3;var n=...
  function S (line 62) | function S(e,t,n,r,o){var i={};return window.___hasFormData=!1,e&&(e=(e+...
  function L (line 62) | function L(e,t,n){if(!e||"string"==typeof e)return e||"";var r=Object.ke...
  function k (line 62) | function k(e){var t=e.realUrl;return/^(?:http|wss)s?:\/\//.test(t)?t:e.url}
  function j (line 62) | function j(e){return"string"==typeof e?e.trim().toLowerCase():e}
  function U (line 62) | function U(e){var t=j(e&&e["content-encoding"]||e);return"gzip"===t||"br...
  function B (line 62) | function B(e){var t=e.indexOf("://");return-1==t?e:e.substring(t+3)}
  function R (line 62) | function R(e){if(!g(e))return"";e=B(e);var t=e.indexOf("/");return-1==t?...
  function z (line 62) | function z(e,t){if(At=!1,"string"==typeof e&&(e=e.trim())){if(t){if(!/({...
  function Q (line 62) | function Q(e){return"number"==typeof e}
  function O (line 62) | function O(e){var t=e.indexOf(": ");-1===t&&(t=e.indexOf(":"),-1===t&&(t...
  function H (line 62) | function H(e){if("string"!=typeof e||!(e=e.trim()))return null;var t;ret...
  function F (line 62) | function F(e,t){window._$hasBigNumberJson=!1;var n=z(e,!0);if(n||!e||!t)...
  function V (line 62) | function V(e){return e.statusCode?"string"==typeof e.statusMessage?e.sta...
  function P (line 62) | function P(e){return/^post$/i.test(e.method)&&/urlencoded/i.test(e.heade...
  function Y (line 62) | function Y(e){return void 0===e?"":e+""}
  function G (line 62) | function G(e){Vt&&"function"==typeof window.customWhistleEditor&&window....
  function W (line 62) | function W(){return document.documentElement.getAttribute("data-theme")|...
  function X (line 62) | function X(e){return e&&(p(e.value)||p(e.base64))&&(e.isFile||g(e.name))...
  function _ (line 62) | function _(e){return!Array.isArray(e)||e.length>2||!g(e[0])?void 0:{rule...
  function q (line 62) | function q(e){if(e){var t=e.whistleTimes||"",n=new Date(t.startTime||e.s...
  function J (line 62) | function J(e){return an[e]}
  function K (line 62) | function K(e,t){if("function"==typeof e.find)return e.find(t);for(var n=...
  function Z (line 62) | function Z(e,t,n){var r=e.pageX,o=e.pageY,i=document.documentElement,a=i...
  function $ (line 62) | function $(e){if(!e.closed&&e.frames){var t=e.frames[e.frames.length-1];...
  function ee (line 62) | function ee(e){return-1===e.indexOf("'")?"'"+e+"'":'"'+e.replace(/"/g,'\...
  function te (line 62) | function te(e){var t={},n={};return Array.isArray(e)&&e.forEach(function...
  function ne (line 62) | function ne(e){return e>0?e:0}
  function re (line 62) | function re(e,t,n){return n.test?!n.test(e):-1===t.toLowerCase().indexOf...
  function oe (line 62) | function oe(e,t){if(!t.key1)return"";var n=e;return ae(re(n,e,t.key1),t....
  function ie (line 62) | function ie(e){var t=e.toLocaleString();if(!cn.test(t))return t;var n=Re...
  function ae (line 62) | function ae(e,t){return t?!e:e}
  function se (line 62) | function se(e){if(e&&un.test(e))try{return new RegExp(RegExp.$1,RegExp.$...
  function le (line 62) | function le(e){return e>0?new Array(e+1).join("0"):""}
  function ce (line 62) | function ce(e,t){return e=e.toString(16).toUpperCase(),le(t-e.length)+e}
  function ue (line 62) | function ue(e){for(var t,n,r=e.length,o=Math.max(6,r.toString(16).length...
  function de (line 62) | function de(e,t){if(!e||"string"!=typeof e)return"";var n=e.replace(gn,"...
  function pe (line 62) | function pe(e){try{return encodeURIComponent(e)}catch(t){}return e}
  function he (line 62) | function he(e){try{return Et(e)}catch(t){}return[]}
  function ge (line 62) | function ge(e){var t=he(e),n={hex:ue(t)};if(!Tt(t))try{n.text=dn.decode(...
  function fe (line 62) | function fe(e){var t=N(e.headers);return t&&"IMG"===I(t)?t:""}
  function me (line 62) | function me(e){if(e)try{return ue(he(e))}catch(t){}return e}
  function Ae (line 62) | function Ae(e){return"Closed"+(e.code?" ("+e.code+")":"")}
  function Me (line 62) | function Me(e,t){if(!e[mn]||!e[An]){if(!e.base64){var n=e.body||e.text;i...
  function we (line 62) | function we(e,t,n){if(null==e[Mn]){var r=ve(e,t);r=r&&F(r,n),e[Mn]=r?{js...
  function ve (line 62) | function ve(e,t){return Me(e,t),e[mn]||""}
  function be (line 62) | function be(e){var t=e.headers&&e.headers["content-type"];return wn.test...
  function ye (line 62) | function ye(e){if(e){var t=e.res,n=I(t.headers),r="IMG"===n;if(r||"HTML"...
  function xe (line 62) | function xe(e,t){try{var n=JSON.parse(e);if(n&&"object"===("undefined"==...
  function Te (line 62) | function Te(e){var t={};return e=e.split(jt),e.forEach(function(e){var n...
  function Ce (line 62) | function Ce(e){return"string"!=typeof e?!1:(e=e.toUpperCase(),!("GET"===...
  function Ne (line 62) | function Ne(e,t,n){return e=parseInt(e,10)||0,t=parseInt(t,10)||0,e===t?...
  function Ie (line 62) | function Ie(e){var t=e.indexOf("  ")+2;return e.substring(t,e.indexOf(" ...
  function Ee (line 62) | function Ee(e){try{var t=window.parent.onWhistlePageChange;"function"==t...
  function De (line 62) | function De(e){var t=location.hash.substring(1),n=t.indexOf("?");t=-1===...
  function Se (line 62) | function Se(e,t,n){var r,o=new FileReader,i=function(e,n){return r?void ...
  function Le (line 62) | function Le(e){var t=e[""],n=Object.keys(e);if(t=t&&(Array.isArray(t)?t:...
  function ke (line 62) | function ke(e){return e>=1024?(e=(e/1024).toFixed(2),1024>e?e+"k":(e=(e/...
  function je (line 62) | function je(e){return e?(e/100).toFixed(2):"0"}
  function Ue (line 62) | function Ue(e,t,n){var r=e.length,o=t&&t.length;if(!r||!o)return-1;var i...
  function Be (line 62) | function Be(e,t,n){var r=e.length,o=t.length,i=new window.Uint8Array(r+o...
  function Re (line 62) | function Re(e){try{return e=kt(e),Et(e)}catch(t){}return null}
  function ze (line 62) | function ze(e){try{return Et(e)}catch(t){}return null}
  function Qe (line 62) | function Qe(e){try{e=St(Dt(e)).split("\r\n")}catch(t){return}if(Dn.test(...
  function Oe (line 62) | function Oe(e){var t=[];return e.value&&t.push(e.value),e.type&&t.push(e...
  function He (line 62) | function He(e,t,n){for(var r="--"+t,o=Re(r+"\r\n"),i=Re("\r\n"+r),a=o.le...
  function Fe (line 62) | function Fe(e){var t='Content-Disposition: form-data; name="'+e.name+'"'...
  function Ve (line 62) | function Ve(){return"----WhistleUploadForm"+Date.now().toString(16)+Math...
  function Pe (line 62) | function Pe(e){var t,n="",r=e.length;for(t=2;r>t;t+=3)n+=Un[e[t-2]>>2],n...
  function Ye (line 62) | function Ye(e){return 10>e?"0"+e:e}
  function Ge (line 62) | function Ge(e){return e>99?e:e>9?"0"+e:"00"+e}
  function We (line 62) | function We(e){e=e||new Date;var t=[];return t.push(e.getFullYear()),t.p...
  function Xe (line 62) | function Xe(e){e=S(e,/;\s*/,null,null,!0);var t={httpOnly:!1,secure:!1};...
  function _e (line 62) | function _e(e,t){var n=[];return e&&(t=t||Bn,Object.keys(e).forEach(func...
  function qe (line 62) | function qe(e,t){return e=S(e,t),_e(e)}
  function Je (line 62) | function Je(e){var t=e.headers||"";return{size:e.unzipSize||e.size||-1,m...
  function Ke (line 62) | function Ke(e){var t,n=e.req,r=e.url,o=n.headers||"",i=qe(o.cookie,/;\s*...
  function Ze (line 62) | function Ze(e){var t=e.res,n=t.headers||"",r=n["set-cookie"];return r=r?...
  function $e (line 62) | function $e(e){e.children&&(e.expand=!0,e.pExpand=!0,e.children.forEach(...
  function et (line 62) | function et(e){e.children&&(e.expand=!1,e.pExpand=!1,e.children.forEach(...
  function tt (line 62) | function tt(e,t){e.children&&(e.pExpand=t,t=e.expand&&t,e.children.forEa...
  function nt (line 62) | function nt(e){e.expand=!0,tt(e,!0)}
  function rt (line 62) | function rt(e){e.expand=!1,tt(e,!1)}
  function ot (line 62) | function ot(e){return e&&"\r"===e[0]}
  function it (line 62) | function it(e,t){return e.regexp?ae(e.regexp.test(t),e.not):ae(-1!==t.to...
  function at (line 62) | function at(e,t,n){if(null==e)return!1;var r="undefined"==typeof e?"unde...
  function st (line 63) | function st(e){return e>=1024?e+" ("+ke(e)+")":e}
  function lt (line 63) | function lt(e){var t="string"==typeof e?e:e.moduleName;return t.substrin...
  function ct (line 63) | function ct(e,t){if(/^(?:https?:\/\/|data:image\/)/.test(t))return t;e=l...
  function ut (line 63) | function ut(e,t,n){return e=e&&e.replace(Fn,"").trim(),e&&-1!==e.indexOf...
  function dt (line 63) | function dt(e){return e&&-1!==e.indexOf("#")?e.replace(Ut,"").trim():e}
  function pt (line 63) | function pt(e){return e.replace(Pn,function(e,t){return t.replace(gn," "...
  function ht (line 63) | function ht(e){var t=/^zh-/i.test(navigator.language||navigator.userLang...
  function n (line 63) | function n(e){return 10>e?"0"+e:e}
  function r (line 63) | function r(){return this.valueOf()}
  function o (line 63) | function o(e){return s.lastIndex=0,s.test(e)?'"'+e.replace(s,function(e)...
  function i (line 63) | function i(e,t){var n,r,s,u,p,h=l,g=t[e];switch(g&&"object"===("undefine...
  function r (line 63) | function r(e,t){"warn"===t?t="warning":"error"===t&&(t="danger");var n=i...
  function r (line 63) | function r(){return s||(s=u('<div class="modal fade w-win-dialog" tabind...
  function o (line 63) | function o(){return l||(l=u('<div class="modal fade w-win-dialog" tabind...
  function i (line 63) | function i(e,t,n){r(),s.find("pre").text(e),s.modal("show");var o=s.find...
  function a (line 63) | function a(e,t,n,r){o(),l.is(":visible")||(l.find(".w-win-delete-all")[n...
  function n (line 63) | function n(e){return r+"?"+e}
  function r (line 63) | function r(e){this.list=C(e),this.isTreeView="1"===D.get("isTreeView"),t...
  function o (line 63) | function o(e){if(e="string"!=typeof e?"":e.trim()){var t="!"===e[0];t&&(...
  function i (line 63) | function i(e){if(e="string"!=typeof e?"":e.trim()){var t,n=function(e){e...
  function a (line 63) | function a(e,t){return e?t.keyword?t.regexp?t.regexp.test(e):-1!==e.toLo...
  function s (line 63) | function s(e,t){if(a((e.isHttps?"tunnel://":"")+e.url,t))return!0;var n=...
  function l (line 63) | function l(e,t){if(c(s(e,t),t.not))return!1;var n=N&&N.getDataKeys(),r=n...
  function c (line 63) | function c(e,t){return t?!e:e}
  function u (line 63) | function u(e){var t=e.res&&e.res.statusCode;return e.reqError||e.resErro...
  function d (line 63) | function d(e,t){switch(t.type){case"mark":return!e.mark||l(e,t);case"c":...
  function p (line 64) | function p(e){return null==e?"":e+""}
  function h (line 64) | function h(e,t){if(!t)return!0;var n="Other"===t;if(n||"WS"===t){if(Q.te...
  function g (line 64) | function g(e,t,n,r){return e==t?0:"-"==e?1:"-"==t?-1:"asc"==n?f(e,t,r):-...
  function f (line 64) | function f(e,t,n){var r=null==t||""==t;if(null==e||""==e)return r?0:-1;i...
  function m (line 64) | function m(e,t){for(var n in e){if(a(n,t))return!0;var r=e[n];if(a(null=...
  function A (line 64) | function A(e,t){var n=e.children;return n?(n.forEach(function(e){A(e,t)}...
  function M (line 64) | function M(e,t,n){if(t>0){var r=w(e);if(n){for(var o=0,i=e.length;t>0&&i...
  function w (line 64) | function w(e){for(var t=0,n=e.length;n>t;t++){var r=e[t];if(r.active)ret...
  function v (line 64) | function v(e,t){for(;e>=0;e--){var n=t[e-1];if(!n||!n.selected&&!n.activ...
  function b (line 64) | function b(e,t){for(var n=t.length;n>e;e++){var r=t[e+1];if(r&&r.data&&(...
  function y (line 64) | function y(e){var t=e.indexOf("?"),n="";if(-1!==t&&(n=e.substring(t),e=e...
  function x (line 64) | function x(e){var t=e.children;if(!t||e.hide)return e.hide;for(var n=!0,...
  function T (line 64) | function T(e,t){for(var n=e.children,r=0,o=n.length;o>r;r++){var i=n[r];...
  function C (line 64) | function C(e,t){var n=e.length;if(n&&(t||!e[n-1].order)){var r=e[0].orde...
  function r (line 64) | function r(e){return e.endTime||e.lost}
  function o (line 64) | function o(e,t){"function"==typeof Object.assign?Object.assign(e,t):Obje...
  function i (line 64) | function i(e){return e&&"string"==typeof e?e:void 0}
  function a (line 64) | function a(e,t,n){var r=e.customData||{};e.customData=r,o(r,t);var a=r.s...
  function s (line 64) | function s(e){if(!h[e]&&window.Worker){var t=new Worker("web-worker.js?i...
  function l (line 64) | function l(e){e.terminate(),e.onmessage=null,e.onerror=null,e.onmessagee...
  function c (line 64) | function c(e){var t=h[e];t&&(delete h[e],l(t))}
  function r (line 64) | function r(e){var t=e.target,n=t.nodeName;return"A"===n?t:(t=t.parentNod...
  function o (line 64) | function o(e){return"string"!=typeof e?"":e.substring(e.indexOf("_")+1)}
  function i (line 64) | function i(e,t){var n=r(e);t&&!n&&(n=u(N(t)).find("a:last")[0]);var i=n&...
  function a (line 64) | function a(e){var t=d.findArray(e.dataTransfer.types,function(e){return ...
  function s (line 64) | function s(e){if("string"!=typeof e)return"";var t=e.lastIndexOf(".");re...
  function e (line 64) | function e(e){t.onDoubleClick(e)}
  function r (line 65) | function r(e){return document.querySelector?document.querySelector(e):o(...
  function e (line 65) | function e(){n=null;var t=c.offsetHeight||0,r=c.offsetWidth||0;10>t||10>...
  function t (line 65) | function t(){n=n||setTimeout(e,30)}
  function e (line 66) | function e(e){return new RegExp("(^|\\s)"+e+"(?:$|\\s)\\s*")}
  function t (line 66) | function t(e){for(var t=e.childNodes.length;t>0;--t)e.removeChild(e.firs...
  function n (line 66) | function n(e,n){return t(e).appendChild(n)}
  function r (line 66) | function r(e,t,n,r){var o=document.createElement(e);if(n&&(o.className=n...
  function o (line 66) | function o(e,t,n,o){var i=r(e,t,n,o);return i.setAttribute("role","prese...
  function i (line 66) | function i(e,t){if(3==t.nodeType&&(t=t.parentNode),e.contains)return e.c...
  function a (line 66) | function a(e){var t,n=e.ownerDocument||e;try{t=e.activeElement}catch(r){...
  function s (line 66) | function s(t,n){var r=t.className;e(n).test(r)||(t.className+=(r?" ":"")...
  function l (line 66) | function l(t,n){for(var r=t.split(" "),o=0;o<r.length;o++)r[o]&&!e(r[o])...
  function c (line 66) | function c(e){return e.display.wrapper.ownerDocument}
  function u (line 66) | function u(e){return d(e.display.wrapper)}
  function d (line 66) | function d(e){return e.getRootNode?e.getRootNode():e.ownerDocument}
  function p (line 66) | function p(e){return c(e).defaultView}
  function h (line 66) | function h(e){var t=Array.prototype.slice.call(arguments,1);return funct...
  function g (line 66) | function g(e,t,n){t||(t={});for(var r in e)!e.hasOwnProperty(r)||n===!1&...
  function f (line 66) | function f(e,t,n,r,o){null==t&&(t=e.search(/[^\s\u00a0]/),-1==t&&(t=e.le...
  function m (line 66) | function m(e,t){for(var n=0;n<e.length;++n)if(e[n]==t)return n;return-1}
  function A (line 66) | function A(e,t,n){for(var r=0,o=0;;){var i=e.indexOf("	",r);-1==i&&(i=e....
  function M (line 66) | function M(e){for(;ns.length<=e;)ns.push(w(ns)+" ");return ns[e]}
  function w (line 66) | function w(e){return e[e.length-1]}
  function v (line 66) | function v(e,t){for(var n=[],r=0;r<e.length;r++)n[r]=t(e[r],r);return n}
  function b (line 66) | function b(e,t,n){for(var r=0,o=n(t);r<e.length&&n(e[r])<=o;)r++;e.splic...
  function y (line 66) | function y(){}
  function x (line 66) | function x(e,t){var n;return Object.create?n=Object.create(e):(y.prototy...
  function T (line 66) | function T(e){return/\w/.test(e)||e>"€"&&(e.toUpperCase()!=e.toLowerCase...
  function C (line 66) | function C(e,t){return t?t.source.indexOf("\\w")>-1&&T(e)?!0:t.test(e):T...
  function N (line 66) | function N(e){for(var t in e)if(e.hasOwnProperty(t)&&e[t])return!1;retur...
  function I (line 66) | function I(e){return e.charCodeAt(0)>=768&&os.test(e)}
  function E (line 66) | function E(e,t,n){for(;(0>n?t>0:t<e.length)&&I(e.charAt(t));)t+=n;return t}
  function D (line 66) | function D(e,t,n){for(var r=t>n?-1:1;;){if(t==n)return t;var o=(t+n)/2,i...
  function S (line 66) | function S(e,t,n,r){if(!e)return r(t,n,"ltr",0);for(var o=!1,i=0;i<e.len...
  function L (line 66) | function L(e,t,n){var r;is=null;for(var o=0;o<e.length;++o){var i=e[o];i...
  function k (line 66) | function k(e,t){var n=e.order;return null==n&&(n=e.order=as(e.text,t)),n}
  function j (line 66) | function j(e,t){return e._handlers&&e._handlers[t]||ss}
  function U (line 66) | function U(e,t,n){if(e.removeEventListener)e.removeEventListener(t,n,!1)...
  function B (line 66) | function B(e,t){var n=j(e,t);if(n.length)for(var r=Array.prototype.slice...
  function R (line 66) | function R(e,t,n){return"string"==typeof t&&(t={type:t,preventDefault:fu...
  function z (line 66) | function z(e){var t=e._handlers&&e._handlers.cursorActivity;if(t)for(var...
  function Q (line 66) | function Q(e,t){return j(e,t).length>0}
  function O (line 66) | function O(e){e.prototype.on=function(e,t){ls(this,e,t)},e.prototype.off...
  function H (line 66) | function H(e){e.preventDefault?e.preventDefault():e.returnValue=!1}
  function F (line 66) | function F(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0}
  function V (line 66) | function V(e){return null!=e.defaultPrevented?e.defaultPrevented:0==e.re...
  function P (line 66) | function P(e){H(e),F(e)}
  function Y (line 66) | function Y(e){return e.target||e.srcElement}
  function G (line 66) | function G(e){var t=e.which;return null==t&&(1&e.button?t=1:2&e.button?t...
  function W (line 66) | function W(e){if(null==qa){var t=r("span","​");n(e,r("span",[t,document....
  function X (line 66) | function X(e){if(null!=Ja)return Ja;var r=n(e,document.createTextNode("A...
  function _ (line 66) | function _(e){if(null!=hs)return hs;var t=n(e,r("span","x")),o=t.getBoun...
  function q (line 66) | function q(e,t){arguments.length>2&&(t.dependencies=Array.prototype.slic...
  function J (line 66) | function J(e,t){fs[e]=t}
  function K (line 66) | function K(e){if("string"==typeof e&&fs.hasOwnProperty(e))e=fs[e];else i...
  function Z (line 66) | function Z(e,t){t=K(t);var n=gs[t.name];if(!n)return Z(e,"text/plain");v...
  function $ (line 66) | function $(e,t){var n=ms.hasOwnProperty(e)?ms[e]:ms[e]={};g(t,n)}
  function ee (line 66) | function ee(e,t){if(t===!0)return t;if(e.copyState)return e.copyState(t)...
  function te (line 66) | function te(e,t){for(var n;e.innerMode&&(n=e.innerMode(t),n&&n.mode!=e);...
  function ne (line 66) | function ne(e,t,n){return e.startState?e.startState(t,n):!0}
  function re (line 66) | function re(e,t){if(t-=e.first,0>t||t>=e.size)throw new Error("There is ...
  function oe (line 66) | function oe(e,t,n){var r=[],o=t.line;return e.iter(t.line,n.line+1,funct...
  function ie (line 66) | function ie(e,t,n){var r=[];return e.iter(t,n,function(e){r.push(e.text)...
  function ae (line 66) | function ae(e,t){var n=t-e.height;if(n)for(var r=e;r;r=r.parent)r.height...
  function se (line 66) | function se(e){if(null==e.parent)return null;for(var t=e.parent,n=m(t.li...
  function le (line 66) | function le(e,t){var n=e.first;e:do{for(var r=0;r<e.children.length;++r)...
  function ce (line 66) | function ce(e,t){return t>=e.first&&t<e.first+e.size}
  function ue (line 66) | function ue(e,t){return String(e.lineNumberFormatter(t+e.firstLineNumber))}
  function de (line 66) | function de(e,t,n){return void 0===n&&(n=null),this instanceof de?(this....
  function pe (line 66) | function pe(e,t){return e.line-t.line||e.ch-t.ch}
  function he (line 66) | function he(e,t){return e.sticky==t.sticky&&0==pe(e,t)}
  function ge (line 66) | function ge(e){return de(e.line,e.ch)}
  function fe (line 66) | function fe(e,t){return pe(e,t)<0?t:e}
  function me (line 66) | function me(e,t){return pe(e,t)<0?e:t}
  function Ae (line 66) | function Ae(e,t){return Math.max(e.first,Math.min(t,e.first+e.size-1))}
  function Me (line 66) | function Me(e,t){if(t.line<e.first)return de(e.first,0);var n=e.first+e....
  function we (line 66) | function we(e,t){var n=e.ch;return null==n||n>t?de(e.line,t):0>n?de(e.li...
  function ve (line 66) | function ve(e,t){for(var n=[],r=0;r<t.length;r++)n[r]=Me(e,t[r]);return n}
  function be (line 66) | function be(e,t,n,r){var o=[e.state.modeGen],i={};De(e,t.text,e.doc.mode...
  function ye (line 66) | function ye(e,t,n){if(!t.styles||t.styles[0]!=e.state.modeGen){var r=xe(...
  function xe (line 66) | function xe(e,t,n){var r=e.doc,o=e.display;if(!r.mode.startState)return ...
  function Te (line 66) | function Te(e,t,n,r){var o=e.doc.mode,i=new As(t,e.options.tabSize,n);fo...
  function Ce (line 66) | function Ce(e,t){if(e.blankLine)return e.blankLine(t);if(e.innerMode){va...
  function Ne (line 66) | function Ne(e,t,n,r){for(var o=0;10>o;o++){r&&(r[0]=te(e,n).mode);var i=...
  function Ie (line 66) | function Ie(e,t,n,r){var o,i=e.doc,a=i.mode;t=Me(i,t);var s,l=re(i,t.lin...
  function Ee (line 66) | function Ee(e,t){if(e)for(;;){var n=e.match(/(?:^|\s+)line-(background-)...
  function De (line 66) | function De(e,t,n,r,o,i,a){var s=n.flattenSpans;null==s&&(s=e.options.fl...
  function Se (line 66) | function Se(e,t,n){for(var r,o,i=e.doc,a=n?-1:t-(e.doc.mode.innerMode?1e...
  function Le (line 66) | function Le(e,t){if(e.modeFrontier=Math.min(e.modeFrontier,t),!(e.highli...
  function ke (line 66) | function ke(){bs=!0}
  function je (line 66) | function je(){ys=!0}
  function Ue (line 66) | function Ue(e,t,n){this.marker=e,this.from=t,this.to=n}
  function Be (line 66) | function Be(e,t){if(e)for(var n=0;n<e.length;++n){var r=e[n];if(r.marker...
  function Re (line 66) | function Re(e,t){for(var n,r=0;r<e.length;++r)e[r]!=t&&(n||(n=[])).push(...
  function ze (line 66) | function ze(e,t,n){var r=n&&window.WeakSet&&(n.markedSpans||(n.markedSpa...
  function Qe (line 66) | function Qe(e,t,n){var r;if(e)for(var o=0;o<e.length;++o){var i=e[o],a=i...
  function Oe (line 66) | function Oe(e,t,n){var r;if(e)for(var o=0;o<e.length;++o){var i=e[o],a=i...
  function He (line 66) | function He(e,t){if(t.full)return null;var n=ce(e,t.from.line)&&re(e,t.f...
  function Fe (line 66) | function Fe(e){for(var t=0;t<e.length;++t){var n=e[t];null!=n.from&&n.fr...
  function Ve (line 66) | function Ve(e,t,n){var r=null;if(e.iter(t.line,n.line+1,function(e){if(e...
  function Pe (line 66) | function Pe(e){var t=e.markedSpans;if(t){for(var n=0;n<t.length;++n)t[n]...
  function Ye (line 66) | function Ye(e,t){if(t){for(var n=0;n<t.length;++n)t[n].marker.attachLine...
  function Ge (line 66) | function Ge(e){return e.inclusiveLeft?-1:0}
  function We (line 66) | function We(e){return e.inclusiveRight?1:0}
  function Xe (line 66) | function Xe(e,t){var n=e.lines.length-t.lines.length;if(0!=n)return n;va...
  function _e (line 66) | function _e(e,t){var n,r=ys&&e.markedSpans;if(r)for(var o=void 0,i=0;i<r...
  function qe (line 66) | function qe(e){return _e(e,!0)}
  function Je (line 66) | function Je(e){return _e(e,!1)}
  function Ke (line 66) | function Ke(e,t){var n,r=ys&&e.markedSpans;if(r)for(var o=0;o<r.length;+...
  function Ze (line 66) | function Ze(e,t,n,r,o){var i=re(e,t),a=ys&&i.markedSpans;if(a)for(var s=...
  function $e (line 66) | function $e(e){for(var t;t=qe(e);)e=t.find(-1,!0).line;return e}
  function et (line 66) | function et(e){for(var t;t=Je(e);)e=t.find(1,!0).line;return e}
  function tt (line 66) | function tt(e){for(var t,n;t=Je(e);)e=t.find(1,!0).line,(n||(n=[])).push...
  function nt (line 66) | function nt(e,t){var n=re(e,t),r=$e(n);return n==r?t:se(r)}
  function rt (line 66) | function rt(e,t){if(t>e.lastLine())return t;var n,r=re(e,t);if(!ot(e,r))...
  function ot (line 66) | function ot(e,t){var n=ys&&t.markedSpans;if(n)for(var r=void 0,o=0;o<n.l...
  function it (line 66) | function it(e,t,n){if(null==n.to){var r=n.marker.find(1,!0);return it(e,...
  function at (line 66) | function at(e){e=$e(e);for(var t=0,n=e.parent,r=0;r<n.lines.length;++r){...
  function st (line 66) | function st(e){if(0==e.height)return 0;for(var t,n=e.text.length,r=e;t=q...
  function lt (line 66) | function lt(e){var t=e.display,n=e.doc;t.maxLine=re(n,n.first),t.maxLine...
  function ct (line 66) | function ct(e,t,n,r){e.text=t,e.stateAfter&&(e.stateAfter=null),e.styles...
  function ut (line 66) | function ut(e){e.parent=null,Pe(e)}
  function dt (line 66) | function dt(e,t){if(!e||/^\s*$/.test(e))return null;var n=t.addModeClass...
  function pt (line 66) | function pt(e,t){var n=o("span",null,null,Ea?"padding-right: .1px":null)...
  function ht (line 67) | function ht(e){var t=r("span","•","cm-invalidchar");return t.title="\\u"...
  function gt (line 67) | function gt(e,t,n,o,i,a,s){if(t){var l,c=e.splitSpaces?ft(t,e.trailingSp...
  function ft (line 67) | function ft(e,t){if(e.length>1&&!/  /.test(e))return e;for(var n=t,r="",...
  function mt (line 67) | function mt(e,t){return function(n,r,o,i,a,s,l){o=o?o+" cm-force-border"...
  function At (line 67) | function At(e,t,n,r){var o=!r&&n.widgetNode;o&&e.map.push(e.pos,e.pos+t,...
  function Mt (line 67) | function Mt(e,t,n){var r=e.markedSpans,o=e.text,i=0;if(r)for(var a,s,l,c...
  function wt (line 67) | function wt(e,t,n){this.line=t,this.rest=tt(t),this.size=this.rest?se(w(...
  function vt (line 67) | function vt(e,t,n){for(var r,o=[],i=t;n>i;i=r){var a=new wt(e.doc,re(e.d...
  function bt (line 67) | function bt(e){Is?Is.ops.push(e):e.ownsGroup=Is={ops:[e],delayedCallback...
  function yt (line 67) | function yt(e){var t=e.delayedCallbacks,n=0;do{for(;n<t.length;n++)t[n]....
  function xt (line 67) | function xt(e,t){var n=e.ownsGroup;if(n)try{yt(n)}finally{Is=null,t(n)}}
  function Tt (line 67) | function Tt(e,t){var n=j(e,t);if(n.length){var r,o=Array.prototype.slice...
  function Ct (line 67) | function Ct(){var e=Es;Es=null;for(var t=0;t<e.length;++t)e[t]()}
  function Nt (line 67) | function Nt(e,t,n,r){for(var o=0;o<t.changes.length;o++){var i=t.changes...
  function It (line 67) | function It(e){return e.node==e.text&&(e.node=r("div",null,null,"positio...
  function Et (line 67) | function Et(e,t){var n=t.bgClass?t.bgClass+" "+(t.line.bgClass||""):t.li...
  function Dt (line 67) | function Dt(e,t){var n=e.display.externalMeasured;return n&&n.line==t.li...
  function St (line 67) | function St(e,t){var n=t.text.className,r=Dt(e,t);t.text==t.node&&(t.nod...
  function Lt (line 67) | function Lt(e,t){Et(e,t),t.line.wrapClass?It(t).className=t.line.wrapCla...
  function kt (line 67) | function kt(e,t,n,o){if(t.gutter&&(t.node.removeChild(t.gutter),t.gutter...
  function jt (line 67) | function jt(t,n,r){n.alignable&&(n.alignable=null);for(var o=e("CodeMirr...
  function Ut (line 67) | function Ut(e,t,n,r){var o=Dt(e,t);return t.text=t.node=o.pre,o.bgClass&...
  function Bt (line 67) | function Bt(e,t,n){if(Rt(e,t.line,t,n,!0),t.rest)for(var r=0;r<t.rest.le...
  function Rt (line 67) | function Rt(e,t,n,o,i){if(t.widgets)for(var a=It(n),s=0,l=t.widgets;s<l....
  function zt (line 67) | function zt(e,t,n,r){if(e.noHScroll){(n.alignable||(n.alignable=[])).pus...
  function Qt (line 67) | function Qt(e){if(null!=e.height)return e.height;var t=e.doc.cm;if(!t)re...
  function Ot (line 67) | function Ot(e,t){for(var n=Y(t);n!=e.wrapper;n=n.parentNode)if(!n||1==n....
  function Ht (line 67) | function Ht(e){return e.lineSpace.offsetTop}
  function Ft (line 67) | function Ft(e){return e.mover.offsetHeight-e.lineSpace.offsetHeight}
  function Vt (line 67) | function Vt(e){if(e.cachedPaddingH)return e.cachedPaddingH;var t=n(e.mea...
  function Pt (line 67) | function Pt(e){return Ka-e.display.nativeBarWidth}
  function Yt (line 67) | function Yt(e){return e.display.scroller.clientWidth-Pt(e)-e.display.bar...
  function Gt (line 67) | function Gt(e){return e.display.scroller.clientHeight-Pt(e)-e.display.ba...
  function Wt (line 67) | function Wt(e,t,n){var r=e.options.lineWrapping,o=r&&Yt(e);if(!t.measure...
  function Xt (line 67) | function Xt(e,t,n){if(e.line==t)return{map:e.measure.map,cache:e.measure...
  function _t (line 67) | function _t(e,t){t=$e(t);var r=se(t),o=e.display.externalMeasured=new wt...
  function qt (line 67) | function qt(e,t,n,r){return Zt(e,Kt(e,t),n,r)}
  function Jt (line 67) | function Jt(e,t){if(t>=e.display.viewFrom&&t<e.display.viewTo)return e.d...
  function Kt (line 67) | function Kt(e,t){var n=se(t),r=Jt(e,n);r&&!r.text?r=null:r&&r.changes&&(...
  function Zt (line 67) | function Zt(e,t,n,r,o){t.before&&(n=-1);var i,a=n+(r||"");return t.cache...
  function $t (line 67) | function $t(e,t,n){for(var r,o,i,a,s,l,c=0;c<e.length;c+=3)if(s=e[c],l=e...
  function en (line 67) | function en(e,t){var n=Ds;if("left"==t)for(var r=0;r<e.length&&(n=e[r])....
  function tn (line 67) | function tn(e,t,n,r){var o,i=$t(t.map,n,r),a=i.node,s=i.start,l=i.end,c=...
  function nn (line 67) | function nn(e,t){if(!window.screen||null==screen.logicalXDPI||screen.log...
  function rn (line 67) | function rn(e){if(e.measure&&(e.measure.cache={},e.measure.heights=null,...
  function on (line 67) | function on(e){e.display.externalMeasure=null,t(e.display.lineMeasure);f...
  function an (line 67) | function an(e){on(e),e.display.cachedCharWidth=e.display.cachedTextHeigh...
  function sn (line 67) | function sn(e){return Sa&&za?-(e.body.getBoundingClientRect().left-parse...
  function ln (line 67) | function ln(e){return Sa&&za?-(e.body.getBoundingClientRect().top-parseI...
  function cn (line 67) | function cn(e){var t=$e(e),n=t.widgets,r=0;if(n)for(var o=0;o<n.length;+...
  function un (line 67) | function un(e,t,n,r,o){if(!o){var i=cn(t);n.top+=i,n.bottom+=i}if("line"...
  function dn (line 67) | function dn(e,t,n){if("div"==n)return t;var r=t.left,o=t.top;if("page"==...
  function pn (line 67) | function pn(e,t,n,r,o){return r||(r=re(e.doc,t.line)),un(e,r,qt(e,r,t.ch...
  function hn (line 67) | function hn(e,t,n,r,o,i){function a(t,a){var s=Zt(e,o,t,a?"right":"left"...
  function gn (line 67) | function gn(e,t){var n=0;t=Me(e.doc,t),e.options.lineWrapping||(n=Tn(e.d...
  function fn (line 67) | function fn(e,t,n,r,o){var i=de(e,t,n);return i.xRel=o,r&&(i.outside=r),i}
  function mn (line 67) | function mn(e,t,n){var r=e.doc;if(n+=e.display.viewOffset,0>n)return fn(...
  function An (line 67) | function An(e,t,n,r){r-=cn(t);var o=t.text.length,i=D(function(t){return...
  function Mn (line 67) | function Mn(e,t,n,r){n||(n=Kt(e,t));var o=un(e,t,Zt(e,n,r),"line").top;r...
  function wn (line 67) | function wn(e,t,n,r){return e.bottom<=n?!1:e.top>n?!0:(r?e.left:e.right)>t}
  function vn (line 67) | function vn(e,t,n,r,o){o-=at(t);var i=Kt(e,t),a=cn(t),s=0,l=t.text.lengt...
  function bn (line 67) | function bn(e,t,n,r,o,i,a){var s=D(function(s){var l=o[s],c=1!=l.level;r...
  function yn (line 67) | function yn(e,t,n,r,o,i,a){var s=An(e,t,r,a),l=s.begin,c=s.end;/\s/.test...
  function xn (line 67) | function xn(e){if(null!=e.cachedTextHeight)return e.cachedTextHeight;if(...
  function Tn (line 67) | function Tn(e){if(null!=e.cachedCharWidth)return e.cachedCharWidth;var t...
  function Cn (line 67) | function Cn(e){for(var t=e.display,n={},r={},o=t.gutters.clientLeft,i=t....
  function Nn (line 67) | function Nn(e){return e.scroller.getBoundingClientRect().left-e.sizer.ge...
  function In (line 67) | function In(e){var t=xn(e.display),n=e.options.lineWrapping,r=n&&Math.ma...
  function En (line 67) | function En(e){var t=e.doc,n=In(e);t.iter(function(e){var t=n(e);t!=e.he...
  function Dn (line 67) | function Dn(e,t,n,r){var o=e.display;if(!n&&"true"==Y(t).getAttribute("c...
  function Sn (line 67) | function Sn(e,t){if(t>=e.display.viewTo)return null;if(t-=e.display.view...
  function Ln (line 67) | function Ln(e,t,n,r){null==t&&(t=e.doc.first),null==n&&(n=e.doc.first+e....
  function kn (line 67) | function kn(e,t,n){e.curOp.viewChanged=!0;var r=e.display,o=e.display.ex...
  function jn (line 67) | function jn(e){e.display.viewFrom=e.display.viewTo=e.doc.first,e.display...
  function Un (line 67) | function Un(e,t,n,r){var o,i=Sn(e,t),a=e.display.view;if(!ys||n==e.doc.f...
  function Bn (line 67) | function Bn(e,t,n){var r=e.display,o=r.view;0==o.length||t>=r.viewTo||n<...
  function Rn (line 67) | function Rn(e){for(var t=e.display.view,n=0,r=0;r<t.length;r++){var o=t[...
  function zn (line 67) | function zn(e){e.display.input.showSelection(e.display.input.prepareSele...
  function Qn (line 67) | function Qn(e,t){void 0===t&&(t=!0);var n=e.doc,r={},o=r.cursors=documen...
  function On (line 67) | function On(e,t,n){var o=hn(e,t,"div",null,null,!e.options.singleCursorH...
  function Hn (line 67) | function Hn(e,t){return e.top-t.top||e.left-t.left}
  function Fn (line 67) | function Fn(e,t,n){function o(e,t,n,o){0>t&&(t=0),t=Math.round(t),o=Math...
  function Vn (line 67) | function Vn(e){if(e.state.focused){var t=e.display;clearInterval(t.blink...
  function Pn (line 67) | function Pn(e){e.hasFocus()||(e.display.input.focus(),e.state.focused||G...
  function Yn (line 67) | function Yn(e){e.state.delayingBlurEvent=!0,setTimeout(function(){e.stat...
  function Gn (line 67) | function Gn(e,t){e.state.delayingBlurEvent&&!e.state.draggingText&&(e.st...
  function Wn (line 67) | function Wn(e,t){e.state.delayingBlurEvent||(e.state.focused&&(B(e,"blur...
  function Xn (line 67) | function Xn(e){for(var t=e.display,n=t.lineDiv.offsetTop,r=Math.max(0,t....
  function _n (line 67) | function _n(e){if(e.widgets)for(var t=0;t<e.widgets.length;++t){var n=e....
  function qn (line 67) | function qn(e,t,n){var r=n&&null!=n.top?Math.max(0,n.top):e.scroller.scr...
  function Jn (line 67) | function Jn(e,t){if(!R(e,"scrollCursorIntoView")){var n=e.display,o=n.si...
  function Kn (line 67) | function Kn(e,t,n,r){null==r&&(r=0);var o;e.options.lineWrapping||t!=n||...
  function Zn (line 67) | function Zn(e,t){var n=$n(e,t);null!=n.scrollTop&&ar(e,n.scrollTop),null...
  function $n (line 67) | function $n(e,t){var n=e.display,r=xn(e.display);t.top<0&&(t.top=0);var ...
  function er (line 67) | function er(e,t){null!=t&&(or(e),e.curOp.scrollTop=(null==e.curOp.scroll...
  function tr (line 67) | function tr(e){or(e);var t=e.getCursor();e.curOp.scrollToPos={from:t,to:...
  function nr (line 67) | function nr(e,t,n){(null!=t||null!=n)&&or(e),null!=t&&(e.curOp.scrollLef...
  function rr (line 67) | function rr(e,t){or(e),e.curOp.scrollToPos=t}
  function or (line 67) | function or(e){var t=e.curOp.scrollToPos;if(t){e.curOp.scrollToPos=null;...
  function ir (line 67) | function ir(e,t,n,r){var o=$n(e,{left:Math.min(t.left,n.left),top:Math.m...
  function ar (line 67) | function ar(e,t){Math.abs(e.doc.scrollTop-t)<2||(ya||kr(e,{top:t}),sr(e,...
  function sr (line 67) | function sr(e,t,n){t=Math.max(0,Math.min(e.display.scroller.scrollHeight...
  function lr (line 67) | function lr(e,t,n,r){t=Math.max(0,Math.min(t,e.display.scroller.scrollWi...
  function cr (line 67) | function cr(e){var t=e.display,n=t.gutters.offsetWidth,r=Math.round(e.do...
  function ur (line 67) | function ur(e,t){t||(t=cr(e));
  function dr (line 68) | function dr(e,t){var n=e.display,r=n.scrollbars.update(t);n.sizer.style....
  function pr (line 68) | function pr(e){e.display.scrollbars&&(e.display.scrollbars.clear(),e.dis...
  function hr (line 68) | function hr(e){e.curOp={cm:e,viewChanged:!1,startHeight:e.doc.height,for...
  function gr (line 68) | function gr(e){var t=e.curOp;t&&xt(t,function(e){for(var t=0;t<e.ops.len...
  function fr (line 68) | function fr(e){for(var t=e.ops,n=0;n<t.length;n++)mr(t[n]);for(var r=0;r...
  function mr (line 68) | function mr(e){var t=e.cm,n=t.display;Ir(t),e.updateMaxLine&&lt(t),e.mus...
  function Ar (line 68) | function Ar(e){e.updatedDisplay=e.mustUpdate&&Sr(e.cm,e.update)}
  function Mr (line 68) | function Mr(e){var t=e.cm,n=t.display;e.updatedDisplay&&Xn(t),e.barMeasu...
  function wr (line 68) | function wr(e){var t=e.cm;null!=e.adjustWidthTo&&(t.display.sizer.style....
  function vr (line 68) | function vr(e){var t=e.cm,n=t.display,r=t.doc;if(e.updatedDisplay&&Lr(t,...
  function br (line 68) | function br(e,t){if(e.curOp)return t();hr(e);try{return t()}finally{gr(e)}}
  function yr (line 68) | function yr(e,t){return function(){if(e.curOp)return t.apply(e,arguments...
  function xr (line 68) | function xr(e){return function(){if(this.curOp)return e.apply(this,argum...
  function Tr (line 68) | function Tr(e){return function(){var t=this.cm;if(!t||t.curOp)return e.a...
  function Cr (line 68) | function Cr(e,t){e.doc.highlightFrontier<e.display.viewTo&&e.state.highl...
  function Nr (line 68) | function Nr(e){var t=e.doc;if(!(t.highlightFrontier>=e.display.viewTo)){...
  function Ir (line 68) | function Ir(e){var t=e.display;!t.scrollbarsClipped&&t.scroller.offsetWi...
  function Er (line 68) | function Er(e){if(e.hasFocus())return null;var t=a(u(e));if(!t||!i(e.dis...
  function Dr (line 68) | function Dr(e){if(e&&e.activeElt&&e.activeElt!=a(d(e.activeElt))&&(e.act...
  function Sr (line 68) | function Sr(e,n){var r=e.display,o=e.doc;if(n.editorIsHidden)return jn(e...
  function Lr (line 68) | function Lr(e,t){for(var n=t.viewport,r=!0;;r=!1){if(r&&e.options.lineWr...
  function kr (line 68) | function kr(e,t){var n=new Us(e,t);if(Sr(e,n)){Xn(e),Lr(e,n);var r=cr(e)...
  function jr (line 68) | function jr(e,n,r){function o(t){var n=t.nextSibling;return Ea&&Oa&&e.di...
  function Ur (line 68) | function Ur(e){var t=e.gutters.offsetWidth;e.sizer.style.marginLeft=t+"p...
  function Br (line 68) | function Br(e,t){e.display.sizer.style.minHeight=t.docHeight+"px",e.disp...
  function Rr (line 68) | function Rr(e){var t=e.display,n=t.view;if(t.alignWidgets||t.gutters.fir...
  function zr (line 68) | function zr(e){if(!e.options.lineNumbers)return!1;var t=e.doc,n=ue(e.opt...
  function Qr (line 68) | function Qr(e,t){for(var n=[],r=!1,o=0;o<e.length;o++){var i=e[o],a=null...
  function Or (line 68) | function Or(e){var n=e.gutters,o=e.gutterSpecs;t(n),e.lineGutter=null;fo...
  function Hr (line 68) | function Hr(e){Or(e.display),Ln(e),Rr(e)}
  function Fr (line 68) | function Fr(e,t,n,i){var a=this;this.input=n,a.scrollbarFiller=r("div",n...
  function Vr (line 68) | function Vr(e){var t=e.wheelDeltaX,n=e.wheelDeltaY;return null==t&&e.det...
  function Pr (line 68) | function Pr(e){var t=Vr(e);return t.x*=Rs,t.y*=Rs,t}
  function Yr (line 68) | function Yr(e,t){Sa&&102==La&&(null==e.display.chromeScrollHack?e.displa...
  function Gr (line 68) | function Gr(e,t,n){var r=e&&e.options.selectionsMayTouch,o=t[n];t.sort(f...
  function Wr (line 68) | function Wr(e,t){return new zs([new Qs(e,t||e)],0)}
  function Xr (line 68) | function Xr(e){return e.text?de(e.from.line+e.text.length-1,w(e.text).le...
  function _r (line 68) | function _r(e,t){if(pe(e,t.from)<0)return e;if(pe(e,t.to)<=0)return Xr(t...
  function qr (line 68) | function qr(e,t){for(var n=[],r=0;r<e.sel.ranges.length;r++){var o=e.sel...
  function Jr (line 68) | function Jr(e,t,n){return e.line==t.line?de(n.line,e.ch-t.ch+n.ch):de(n....
  function Kr (line 68) | function Kr(e,t,n){for(var r=[],o=de(e.first,0),i=o,a=0;a<t.length;a++){...
  function Zr (line 68) | function Zr(e){e.doc.mode=Z(e.options,e.doc.modeOption),$r(e)}
  function $r (line 68) | function $r(e){e.doc.iter(function(e){e.stateAfter&&(e.stateAfter=null),...
  function eo (line 68) | function eo(e,t){return 0==t.from.ch&&0==t.to.ch&&""==w(t.text)&&(!e.cm|...
  function to (line 68) | function to(e,t,n,r){function o(e){return n?n[e]:null}function i(e,n,o){...
  function no (line 68) | function no(e,t,n){function r(e,o,i){if(e.linked)for(var a=0;a<e.linked....
  function ro (line 68) | function ro(e,t){if(t.cm)throw new Error("This document is already in us...
  function oo (line 68) | function oo(e){("rtl"==e.doc.direction?s:Wa)(e.display.lineDiv,"CodeMirr...
  function io (line 68) | function io(e){br(e,function(){oo(e),Ln(e)})}
  function ao (line 68) | function ao(e){this.done=[],this.undone=[],this.undoDepth=e?e.undoDepth:...
  function so (line 68) | function so(e,t){var n={from:ge(t.from),to:Xr(t),text:oe(e,t.from,t.to)}...
  function lo (line 68) | function lo(e){for(;e.length;){var t=w(e);if(!t.ranges)break;e.pop()}}
  function co (line 68) | function co(e,t){return t?(lo(e.done),w(e.done)):e.done.length&&!w(e.don...
  function uo (line 68) | function uo(e,t,n,r){var o=e.history;o.undone.length=0;var i,a,s=+new Da...
  function po (line 68) | function po(e,t,n,r){var o=t.charAt(0);return"*"==o||"+"==o&&n.ranges.le...
  function ho (line 68) | function ho(e,t,n,r){var o=e.history,i=r&&r.origin;n==o.lastSelOp||i&&o....
  function go (line 68) | function go(e,t){var n=w(t);n&&n.ranges&&n.equals(e)||t.push(e)}
  function fo (line 68) | function fo(e,t,n,r){var o=t["spans_"+e.id],i=0;e.iter(Math.max(e.first,...
  function mo (line 68) | function mo(e){if(!e)return null;for(var t,n=0;n<e.length;++n)e[n].marke...
  function Ao (line 68) | function Ao(e,t){var n=t["spans_"+e.id];if(!n)return null;for(var r=[],o...
  function Mo (line 68) | function Mo(e,t){var n=Ao(e,t),r=He(e,t);if(!n)return r;if(!r)return n;f...
  function wo (line 68) | function wo(e,t,n){for(var r=[],o=0;o<e.length;++o){var i=e[o];if(i.rang...
  function vo (line 68) | function vo(e,t,n,r){if(r){var o=e.anchor;if(n){var i=pe(t,o)<0;i!=pe(n,...
  function bo (line 68) | function bo(e,t,n,r,o){null==o&&(o=e.cm&&(e.cm.display.shift||e.extend))...
  function yo (line 68) | function yo(e,t,n){for(var r=[],o=e.cm&&(e.cm.display.shift||e.extend),i...
  function xo (line 68) | function xo(e,t,n,r){var o=e.sel.ranges.slice(0);o[t]=n,Io(e,Gr(e.cm,o,e...
  function To (line 68) | function To(e,t,n,r){Io(e,Wr(t,n),r)}
  function Co (line 68) | function Co(e,t,n){var r={ranges:t.ranges,update:function(t){this.ranges...
  function No (line 68) | function No(e,t,n){var r=e.history.done,o=w(r);o&&o.ranges?(r[r.length-1...
  function Io (line 68) | function Io(e,t,n){Eo(e,t,n),ho(e,e.sel,e.cm?e.cm.curOp.id:NaN,n)}
  function Eo (line 68) | function Eo(e,t,n){(Q(e,"beforeSelectionChange")||e.cm&&Q(e.cm,"beforeSe...
  function Do (line 68) | function Do(e,t){t.equals(e.sel)||(e.sel=t,e.cm&&(e.cm.curOp.updateInput...
  function So (line 68) | function So(e){Do(e,Lo(e,e.sel,null,!1))}
  function Lo (line 68) | function Lo(e,t,n,r){for(var o,i=0;i<t.ranges.length;i++){var a=t.ranges...
  function ko (line 68) | function ko(e,t,n,r,o){var i=re(e,t.line);if(i.markedSpans)for(var a=0;a...
  function jo (line 68) | function jo(e,t,n,r,o){var i=r||1,a=ko(e,t,n,i,o)||!o&&ko(e,t,n,i,!0)||k...
  function Uo (line 68) | function Uo(e,t,n,r){return 0>n&&0==t.ch?t.line>e.first?Me(e,de(t.line-1...
  function Bo (line 68) | function Bo(e){e.setSelection(de(e.firstLine(),0),de(e.lastLine()),$a)}
  function Ro (line 68) | function Ro(e,t,n){var r={canceled:!1,from:t.from,to:t.to,text:t.text,or...
  function zo (line 68) | function zo(e,t,n){if(e.cm){if(!e.cm.curOp)return yr(e.cm,zo)(e,t,n);if(...
  function Qo (line 68) | function Qo(e,t){if(1!=t.text.length||""!=t.text[0]||0!=pe(t.from,t.to))...
  function Oo (line 68) | function Oo(e,t,n){var r=e.cm&&e.cm.state.suppressEdits;if(!r||n){for(va...
  function Ho (line 68) | function Ho(e,t){if(0!=t&&(e.first+=t,e.sel=new zs(v(e.sel.ranges,functi...
  function Fo (line 68) | function Fo(e,t,n,r){if(e.cm&&!e.cm.curOp)return yr(e.cm,Fo)(e,t,n,r);if...
  function Vo (line 68) | function Vo(e,t,n){var r=e.doc,o=e.display,i=t.from,a=t.to,s=!1,l=i.line...
  function Po (line 68) | function Po(e,t,n,r,o){var i;r||(r=n),pe(r,n)<0&&(i=[r,n],n=i[0],r=i[1])...
  function Yo (line 68) | function Yo(e,t,n,r){n<e.line?e.line+=r:t<e.line&&(e.line=t,e.ch=0)}
  function Go (line 68) | function Go(e,t,n,r){for(var o=0;o<e.length;++o){var i=e[o],a=!0;if(i.ra...
  function Wo (line 68) | function Wo(e,t){var n=t.from.line,r=t.to.line,o=t.text.length-(r-n)-1;G...
  function Xo (line 68) | function Xo(e,t,n,r){var o=t,i=t;return"number"==typeof t?i=re(e,Ae(e,t)...
  function _o (line 68) | function _o(e){this.lines=e,this.parent=null;for(var t=0,n=0;n<e.length;...
  function qo (line 68) | function qo(e){this.children=e;for(var t=0,n=0,r=0;r<e.length;++r){var o...
  function Jo (line 68) | function Jo(e,t,n){at(t)<(e.curOp&&e.curOp.scrollTop||e.doc.scrollTop)&&...
  function Ko (line 68) | function Ko(e,t,n,r){var o=new Os(e,n,r),i=e.cm;return i&&o.noHScroll&&(...
  function Zo (line 68) | function Zo(e,t,n,r,i){if(r&&r.shared)return $o(e,t,n,r,i);if(e.cm&&!e.c...
  function $o (line 68) | function $o(e,t,n,r,o){r=g(r),r.shared=!1;var i=[Zo(e,t,n,r,o)],a=i[0],s...
  function ei (line 68) | function ei(e){return e.findMarks(de(e.first,0),e.clipPos(de(e.lastLine(...
  function ti (line 68) | function ti(e,t){for(var n=0;n<t.length;n++){var r=t[n],o=r.find(),i=e.c...
  function ni (line 68) | function ni(e){for(var t=function(t){var n=e[t],r=[n.primary.doc];no(n.p...
  function ri (line 68) | function ri(e){var t=this;if(ai(t),!R(t,e)&&!Ot(t.display,e)){H(e),Na&&(...
  function oi (line 69) | function oi(e,t){if(Na&&(!e.state.draggingText||+new Date-Gs<100))return...
  function ii (line 69) | function ii(e,t){var o=Dn(e,t);if(o){var i=document.createDocumentFragme...
  function ai (line 69) | function ai(e){e.display.dragCursor&&(e.display.lineSpace.removeChild(e....
  function si (line 69) | function si(e){if(document.getElementsByClassName){for(var t=document.ge...
  function li (line 69) | function li(){Ws||(ci(),Ws=!0)}
  function ci (line 69) | function ci(){var e;ls(window,"resize",function(){null==e&&(e=setTimeout...
  function ui (line 69) | function ui(e){var t=e.display;t.cachedCharWidth=t.cachedTextHeight=t.ca...
  function di (line 69) | function di(e){var t=e.split(/-(?!$)/);e=t[t.length-1];for(var n,r,o,i,a...
  function pi (line 69) | function pi(e){var t={};for(var n in e)if(e.hasOwnProperty(n)){var r=e[n...
  function hi (line 69) | function hi(e,t,n,r){t=Ai(t);var o=t.call?t.call(e,r):t[e];if(o===!1)ret...
  function gi (line 69) | function gi(e){var t="string"==typeof e?e:Xs[e.keyCode];return"Ctrl"==t|...
  function fi (line 69) | function fi(e,t,n){var r=e;return t.altKey&&"Alt"!=r&&(e="Alt-"+e),(Ya?t...
  function mi (line 69) | function mi(e,t){if(ka&&34==e.keyCode&&e["char"])return!1;var n=Xs[e.key...
  function Ai (line 69) | function Ai(e){return"string"==typeof e?Ks[e]:e}
  function Mi (line 69) | function Mi(e,t){for(var n=e.doc.sel.ranges,r=[],o=0;o<n.length;o++){for...
  function wi (line 69) | function wi(e,t,n){var r=E(e.text,t+n,n);return 0>r||r>e.text.length?nul...
  function vi (line 69) | function vi(e,t,n){var r=wi(e,t.ch,n);return null==r?null:new de(t.line,...
  function bi (line 69) | function bi(e,t,n,r,o){if(e){"rtl"==t.doc.direction&&(o=-o);var i=k(n,t....
  function yi (line 69) | function yi(e,t,n,r){var o=k(t,e.doc.direction);if(!o)return vi(t,n,r);n...
  function xi (line 69) | function xi(e,t){var n=re(e.doc,t),r=$e(n);return r!=n&&(t=se(r)),bi(!0,...
  function Ti (line 69) | function Ti(e,t){var n=re(e.doc,t),r=et(n);return r!=n&&(t=se(r)),bi(!0,...
  function Ci (line 69) | function Ci(e,t){var n=xi(e,t.line),r=re(e.doc,n.line),o=k(r,e.doc.direc...
  function Ni (line 69) | function Ni(e,t,n){if("string"==typeof t&&(t=Zs[t],!t))return!1;e.displa...
  function Ii (line 69) | function Ii(e,t,n){for(var r=0;r<e.state.keyMaps.length;r++){var o=hi(t,...
  function Ei (line 69) | function Ei(e,t,n,r){var o=e.state.keySeq;if(o){if(gi(t))return"handled"...
  function Di (line 69) | function Di(e,t,n,r){var o=Ii(e,t,r);return"multi"==o&&(e.state.keySeq=t...
  function Si (line 69) | function Si(e,t){var n=mi(t,!0);return n?t.shiftKey&&!e.state.keySeq?Ei(...
  function Li (line 69) | function Li(e,t,n){return Ei(e,"'"+n+"'",t,function(t){return Ni(e,t,!0)})}
  function ki (line 69) | function ki(e){var t=this;if(!(e.target&&e.target!=t.display.input.getFi...
  function ji (line 69) | function ji(e){function t(e){18!=e.keyCode&&e.altKey||(Wa(n,"CodeMirror-...
  function Ui (line 69) | function Ui(e){16==e.keyCode&&(this.doc.sel.shift=!1),R(this,e)}
  function Bi (line 69) | function Bi(e){var t=this;if(!(e.target&&e.target!=t.display.input.getFi...
  function Ri (line 69) | function Ri(e,t){var n=+new Date;return ol&&ol.compare(n,e,t)?(rl=ol=nul...
  function zi (line 69) | function zi(e){var t=this,n=t.display;if(!(R(t,e)||n.activeTouch&&n.inpu...
  function Qi (line 69) | function Qi(e,t,n,r,o){var i="Click";return"double"==r?i="Double"+i:"tri...
  function Oi (line 69) | function Oi(e,t,n){var r=e.getOption("configureMouse"),o=r?r(e,t,n):{};i...
  function Hi (line 69) | function Hi(e,t,n,r){Na?setTimeout(h(Pn,e),0):e.curOp.focus=a(u(e));var ...
  function Fi (line 69) | function Fi(e,t,n,r){var o=e.display,i=!1,a=yr(e,function(t){Ea&&(o.scro...
  function Vi (line 69) | function Vi(e,t,n){if("char"==n)return new Qs(t,t);if("word"==n)return e...
  function Pi (line 69) | function Pi(e,t,n,r){function o(t){if(0!=pe(M,t))if(M=t,"rectangle"==r.u...
  function Yi (line 69) | function Yi(e,t){var n=t.anchor,r=t.head,o=re(e.doc,n.line);if(0==pe(n,r...
  function Gi (line 69) | function Gi(e,t,n,r){var o,i;if(t.touches)o=t.touches[0].clientX,i=t.tou...
  function Wi (line 69) | function Wi(e,t){return Gi(e,t,"gutterClick",!0)}
  function Xi (line 69) | function Xi(e,t){Ot(e.display,t)||_i(e,t)||R(e,t,"contextmenu")||Ga||e.d...
  function _i (line 69) | function _i(e,t){return Q(e,"gutterContextMenu")?Gi(e,t,"gutterContextMe...
  function qi (line 69) | function qi(e){e.display.wrapper.className=e.display.wrapper.className.r...
  function Ji (line 69) | function Ji(e){function t(t,r,o,i){e.defaults[t]=r,o&&(n[t]=i?function(e...
  function Ki (line 69) | function Ki(e,t,n){var r=n&&n!=il;if(!t!=!r){var o=e.display.dragFunctio...
  function Zi (line 69) | function Zi(e){e.options.lineWrapping?(s(e.display.wrapper,"CodeMirror-w...
  function $i (line 69) | function $i(e,t){var n=this;if(!(this instanceof $i))return new $i(e,t);...
  function ea (line 69) | function ea(e){function t(){o.activeTouch&&(i=setTimeout(function(){retu...
  function ta (line 69) | function ta(e,t,n,r){var o,i=e.doc;null==n&&(n="add"),"smart"==n&&(i.mod...
  function na (line 69) | function na(e){cl=e}
  function ra (line 69) | function ra(e,t,n,r,o){var i=e.doc;e.display.shift=!1,r||(r=i.sel);var a...
  function oa (line 69) | function oa(e,t){var n=e.clipboardData&&e.clipboardData.getData("Text");...
  function ia (line 69) | function ia(e,t){if(e.options.electricChars&&e.options.smartIndent)for(v...
  function aa (line 69) | function aa(e){for(var t=[],n=[],r=0;r<e.doc.sel.ranges.length;r++){var ...
  function sa (line 69) | function sa(e,t,n,r){e.setAttribute("autocorrect",n?"on":"off"),e.setAtt...
  function la (line 69) | function la(){var e=r("textarea",null,null,"position: absolute; bottom: ...
  function ca (line 69) | function ca(e){var t=e.optionHandlers,n=e.helpers={};e.prototype={constr...
  function ua (line 70) | function ua(e,t,n,r,o){function i(){var n=t.line+u;return n<e.first||n>=...
  function da (line 70) | function da(e,t,n,r){var o,i=e.doc,a=t.left;if("page"==r){var s=Math.min...
  function pa (line 70) | function pa(e,t){var n=Jt(e,t.line);if(!n||n.hidden)return null;var r=re...
  function ha (line 70) | function ha(e){for(var t=e;t;t=t.parentNode)if(/CodeMirror-gutter-wrappe...
  function ga (line 70) | function ga(e,t){return t&&(e.bad=!0),e}
  function fa (line 70) | function fa(e,t,n,r,o){function i(e){return function(t){return t.id==e}}...
  function ma (line 70) | function ma(e,t,n){var r;if(t==e.display.lineDiv){if(r=e.display.lineDiv...
  function Aa (line 70) | function Aa(e,t,n){function r(t,n,r){for(var o=-1;o<(d?d.length:0);o++)f...
  function Ma (line 70) | function Ma(e,t){function n(){e.value=c.getValue()}if(t=t?g(t):{},t.valu...
  function wa (line 70) | function wa(e){e.off=U,e.on=ls,e.wheelEventPixels=Pr,e.Doc=Ys,e.splitLin...
  function e (line 70) | function e(e){return 247>=e?n.charAt(e):e>=1424&&1524>=e?"R":e>=1536&&17...
  function t (line 70) | function t(e,t,n){this.level=e,this.from=t,this.to=n}
  function r (line 70) | function r(){var o=e.getBoundingClientRect(),i="vert"==n?document.elemen...
  function t (line 71) | function t(e){for(var t=e.target;t;t=t.parentNode){if(t==s)return!0;if(/...
  function n (line 71) | function n(e){if(t(e)&&!R(i,e)){if(i.somethingSelected())na({lineWise:!1...
  function e (line 71) | function e(){n.cm.state.focused&&(n.pollSelection(),n.polling.set(n.cm.o...
  function t (line 71) | function t(e){if(!R(o,e)){if(o.somethingSelected())na({lineWise:!1,text:...
  function e (line 71) | function e(){var r=n.poll();r||t?(n.pollingFast=!1,n.slowPoll()):(t=!0,n...
  function t (line 71) | function t(){if(null!=a.selectionStart){var e=o.somethingSelected(),t="​...
  function n (line 71) | function n(){if(r.contextMenuPending==n&&(r.contextMenuPending=!1,r.wrap...
  function r (line 71) | function r(e){for(var t,n=!1,r=!1;null!=(t=e.next());){if(!n){if("/"==t&...
  function o (line 71) | function o(e,t,n){return Pe=e,Ye=n,t}
  function i (line 71) | function i(e,t){var n=e.next();if('"'==n||"'"==n)return t.tokenize=a(n),...
  function a (line 71) | function a(e){return function(t,n){var r,a=!1;if(Xe&&"@"==t.peek()&&t.ma...
  function s (line 71) | function s(e,t){for(var n,r=!1;n=e.next();){if("/"==n&&r){t.tokenize=i;b...
  function l (line 71) | function l(e,t){for(var n,r=!1;null!=(n=e.next());){if(!r&&("`"==n||"$"=...
  function c (line 71) | function c(e,t){t.fatArrowAt&&(t.fatArrowAt=null);var n=e.string.indexOf...
  function u (line 71) | function u(e,t,n,r,o,i){this.indented=e,this.column=t,this.type=n,this.p...
  function d (line 71) | function d(e,t){if(!qe)return!1;for(var n=e.localVars;n;n=n.next)if(n.na...
  function p (line 71) | function p(e,t,n,r,o){var i=e.cc;for(rt.state=e,rt.stream=o,rt.marked=nu...
  function h (line 71) | function h(){for(var e=arguments.length-1;e>=0;e--)rt.cc.push(arguments[...
  function g (line 71) | function g(){return h.apply(null,arguments),!0}
  function f (line 71) | function f(e,t){for(var n=t;n;n=n.next)if(n.name==e)return!0;return!1}
  function m (line 71) | function m(e){var t=rt.state;if(rt.marked="def",qe){if(t.context)if("var...
  function A (line 71) | function A(e,t){if(t){if(t.block){var n=A(e,t.prev);return n?n==t.prev?t...
  function M (line 71) | function M(e){return"public"==e||"private"==e||"protected"==e||"abstract...
  function w (line 71) | function w(e,t,n){this.prev=e,this.vars=t,this.block=n}
  function v (line 71) | function v(e,t){this.name=e,this.next=t}
  function b (line 71) | function b(){
  function y (line 72) | function y(){rt.state.context=new w(rt.state.context,rt.state.localVars,...
  function x (line 72) | function x(){rt.state.localVars=rt.state.context.vars,rt.state.context=r...
  function T (line 72) | function T(e,t){var n=function(){var n=rt.state,r=n.indented;if("stat"==...
  function C (line 72) | function C(){var e=rt.state;e.lexical.prev&&(")"==e.lexical.type&&(e.ind...
  function N (line 72) | function N(e){function t(n){return n==e?g():";"==e||"}"==n||")"==n||"]"=...
  function I (line 72) | function I(e,t){return"var"==e?g(T("vardef",t),pe,N(";"),C):"keyword a"=...
  function E (line 72) | function E(e){return"("==e?g(Ce,N(")")):void 0}
  function D (line 72) | function D(e,t){return k(e,t,!1)}
  function S (line 72) | function S(e,t){return k(e,t,!0)}
  function L (line 72) | function L(e){return"("!=e?h():g(T(")"),j,N(")"),C)}
  function k (line 72) | function k(e,t,n){if(rt.state.fatArrowAt==rt.stream.start){var r=n?O:Q;i...
  function j (line 72) | function j(e){return e.match(/[;\}\)\],]/)?h():h(D)}
  function U (line 72) | function U(e,t){return","==e?g(j):B(e,t,!1)}
  function B (line 72) | function B(e,t,n){var r=0==n?U:B,o=0==n?D:S;return"=>"==e?g(b,n?O:Q,x):"...
  function R (line 72) | function R(e,t){return"quasi"!=e?h():"${"!=t.slice(t.length-2)?g(R):g(j,z)}
  function z (line 72) | function z(e){return"}"==e?(rt.marked="string-2",rt.state.tokenize=l,g(R...
  function Q (line 72) | function Q(e){return c(rt.stream,rt.state),h("{"==e?I:D)}
  function O (line 72) | function O(e){return c(rt.stream,rt.state),h("{"==e?I:S)}
  function H (line 72) | function H(e){return function(t){return"."==t?g(e?V:F):"variable"==t&&Je...
  function F (line 72) | function F(e,t){return"target"==t?(rt.marked="keyword",g(U)):void 0}
  function V (line 72) | function V(e,t){return"target"==t?(rt.marked="keyword",g(B)):void 0}
  function P (line 72) | function P(e){return":"==e?g(C,I):h(U,N(";"),C)}
  function Y (line 72) | function Y(e){return"variable"==e?(rt.marked="property",g()):void 0}
  function G (line 72) | function G(e,t){if("async"==e)return rt.marked="property",g(G);if("varia...
  function W (line 72) | function W(e){return"variable"!=e?h(X):(rt.marked="property",g(ye))}
  function X (line 72) | function X(e){return":"==e?g(S):"("==e?h(ye):void 0}
  function _ (line 72) | function _(e,t,n){function r(o,i){if(n?n.indexOf(o)>-1:","==o){var a=rt....
  function q (line 72) | function q(e,t,n){for(var r=3;r<arguments.length;r++)rt.cc.push(argument...
  function J (line 72) | function J(e){return"}"==e?g():h(I,J)}
  function K (line 72) | function K(e,t){if(Je){if(":"==e)return g(te);if("?"==t)return g(K)}}
  function Z (line 72) | function Z(e,t){return!Je||":"!=e&&"in"!=t?void 0:g(te)}
  function $ (line 72) | function $(e){return Je&&":"==e?rt.stream.match(/^\s*\w+\s+is\b/,!1)?g(D...
  function ee (line 72) | function ee(e,t){return"is"==t?(rt.marked="keyword",g()):void 0}
  function te (line 72) | function te(e,t){return"keyof"==t||"typeof"==t||"infer"==t||"readonly"==...
  function ne (line 72) | function ne(e){return"=>"==e?g(te):void 0}
  function re (line 72) | function re(e){return e.match(/[\}\)\]]/)?g():","==e||";"==e?g(re):h(oe,...
  function oe (line 72) | function oe(e,t){return"variable"==e||"keyword"==rt.style?(rt.marked="pr...
  function ie (line 72) | function ie(e,t){return"quasi"!=e?h():"${"!=t.slice(t.length-2)?g(ie):g(...
  function ae (line 72) | function ae(e){return"}"==e?(rt.marked="string-2",rt.state.tokenize=l,g(...
  function se (line 72) | function se(e,t){return"variable"==e&&rt.stream.match(/^\s*[?:]/,!1)||"?...
  function le (line 72) | function le(e,t){return"<"==t?g(T(">"),_(te,">"),C,le):"|"==t||"."==e||"...
  function ce (line 72) | function ce(e,t){return"<"==t?g(T(">"),_(te,">"),C,le):void 0}
  function ue (line 72) | function ue(){return h(te,de)}
  function de (line 72) | function de(e,t){return"="==t?g(te):void 0}
  function pe (line 72) | function pe(e,t){return"enum"==t?(rt.marked="keyword",g(Oe)):h(he,K,me,Ae)}
  function he (line 72) | function he(e,t){return Je&&M(t)?(rt.marked="keyword",g(he)):"variable"=...
  function ge (line 72) | function ge(e,t){return"variable"!=e||rt.stream.match(/^\s*:/,!1)?("vari...
  function fe (line 72) | function fe(){return h(he,me)}
  function me (line 72) | function me(e,t){return"="==t?g(S):void 0}
  function Ae (line 72) | function Ae(e){return","==e?g(pe):void 0}
  function Me (line 72) | function Me(e,t){return"keyword b"==e&&"else"==t?g(T("form","else"),I,C)...
  function we (line 72) | function we(e,t){return"await"==t?g(we):"("==e?g(T(")"),ve,C):void 0}
  function ve (line 72) | function ve(e){return"var"==e?g(pe,be):"variable"==e?g(be):h(be)}
  function be (line 72) | function be(e,t){return")"==e?g():";"==e?g(be):"in"==t||"of"==t?(rt.mark...
  function ye (line 72) | function ye(e,t){return"*"==t?(rt.marked="keyword",g(ye)):"variable"==e?...
  function xe (line 72) | function xe(e,t){return"*"==t?(rt.marked="keyword",g(xe)):"variable"==e?...
  function Te (line 72) | function Te(e,t){return"keyword"==e||"variable"==e?(rt.marked="type",g(T...
  function Ce (line 72) | function Ce(e,t){return"@"==t&&g(D,Ce),"spread"==e?g(Ce):Je&&M(t)?(rt.ma...
  function Ne (line 72) | function Ne(e,t){return"variable"==e?Ie(e,t):Ee(e,t)}
  function Ie (line 72) | function Ie(e,t){return"variable"==e?(m(t),g(Ee)):void 0}
  function Ee (line 72) | function Ee(e,t){return"<"==t?g(T(">"),_(ue,">"),C,Ee):"extends"==t||"im...
  function De (line 72) | function De(e,t){return"async"==e||"variable"==e&&("static"==t||"get"==t...
  function Se (line 72) | function Se(e,t){if("!"==t)return g(Se);if("?"==t)return g(Se);if(":"==e...
  function Le (line 72) | function Le(e,t){return"*"==t?(rt.marked="keyword",g(ze,N(";"))):"defaul...
  function ke (line 72) | function ke(e,t){return"as"==t?(rt.marked="keyword",g(N("variable"))):"v...
  function je (line 72) | function je(e){return"string"==e?g():"("==e?h(D):"."==e?h(U):h(Ue,Be,ze)}
  function Ue (line 72) | function Ue(e,t){return"{"==e?q(Ue,"}"):("variable"==e&&m(t),"*"==t&&(rt...
  function Be (line 72) | function Be(e){return","==e?g(Ue,Be):void 0}
  function Re (line 72) | function Re(e,t){return"as"==t?(rt.marked="keyword",g(Ue)):void 0}
  function ze (line 72) | function ze(e,t){return"from"==t?(rt.marked="keyword",g(D)):void 0}
  function Qe (line 72) | function Qe(e){return"]"==e?g():h(_(S,"]"))}
  function Oe (line 72) | function Oe(){return h(T("form"),he,N("{"),T("}"),_(He,"}"),C,C)}
  function He (line 72) | function He(){return h(he,me)}
  function Fe (line 72) | function Fe(e,t){return"operator"==e.lastType||","==e.lastType||$e.test(...
  function Ve (line 72) | function Ve(e,t,n){return t.tokenize==i&&/^(?:operator|sof|keyword [bcd]...
  function e (line 72) | function e(e){return{type:e,style:"keyword"}}
  function t (line 72) | function t(e){for(var t={},n=0;n<e.length;++n)t[e[n].toLowerCase()]=!0;r...
  function n (line 72) | function n(e,t){for(var n,r=!1;null!=(n=e.next());){if(r&&"/"==n){t.toke...
  function r (line 72) | function r(e,t){return g=t,e}
  function o (line 72) | function o(e,t){var n=e.next();if(A[n]){var o=A[n](e,t);if(o!==!1)return...
  function i (line 72) | function i(e){return function(t,n){for(var o,i=!1;null!=(o=t.next());){i...
  function a (line 72) | function a(e,t){return e.next(),e.match(/^\s*[\"\')]/,!1)?t.tokenize=nul...
  function s (line 72) | function s(e,t,n){this.type=e,this.indent=t,this.prev=n}
  function l (line 72) | function l(e,t,n,r){return e.context=new s(n,t.indentation()+(r===!1?0:m...
  function c (line 72) | function c(e){return e.context.prev&&(e.context=e.context.prev),e.contex...
  function u (line 72) | function u(e,t,n){return k[n.context.type](e,t,n)}
  function d (line 72) | function d(e,t,n,r){for(var o=r||1;o>0;o--)n.context=n.context.prev;retu...
  function p (line 72) | function p(e){var t=e.current().toLowerCase();f=I.hasOwnProperty(t)?"ato...
  function i (line 73) | function i(e,t){function n(n){return t.tokenize=n,n(e,t)}var r=e.next();...
  function a (line 73) | function a(e,t){var n=e.next();if(">"==n||"/"==n&&e.eat(">"))return t.to...
  function s (line 73) | function s(e){var t=function(t,n){for(;!t.eol();)if(t.next()==e){n.token...
  function l (line 73) | function l(e,t){return function(n,r){for(;!n.eol();){if(n.match(t)){r.to...
  function c (line 73) | function c(e){return function(t,n){for(var r;null!=(r=t.next());){if("<"...
  function u (line 73) | function u(e){return e&&e.toLowerCase()}
  function d (line 73) | function d(e,t,n){this.prev=e.context,this.tagName=t||"",this.indent=e.i...
  function p (line 73) | function p(e){e.context&&(e.context=e.context.prev)}
  function h (line 73) | function h(e,t){for(var n;;){if(!e.context)return;if(n=e.context.tagName...
  function g (line 73) | function g(e,t,n){return"openTag"==e?(n.tagStart=t.column(),f):"closeTag...
  function f (line 73) | function f(e,t,n){return"word"==e?(n.tagName=t.current(),E="tag",w):T.al...
  function m (line 73) | function m(e,t,n){if("word"==e){var r=t.current();return n.context&&n.co...
  function A (line 73) | function A(e,t,n){return"endTag"!=e?(E="error",A):(p(n),g)}
  function M (line 73) | function M(e,t,n){return E="error",A(e,t,n)}
  function w (line 73) | function w(e,t,n){if("word"==e)return E="attribute",v;if("endTag"==e||"s...
  function v (line 73) | function v(e,t,n){return"equals"==e?b:(T.allowMissing||(E="error"),w(e,t...
  function b (line 73) | function b(e,t,n){return"string"==e?y:"word"==e&&T.allowUnquoted?(E="str...
  function y (line 73) | function y(e,t,n){return"string"==e?y:w(e,t,n)}
  function t (line 73) | function t(e,t,n){var r=e.current(),o=r.search(t);return o>-1?e.backUp(r...
  function n (line 73) | function n(e){var t=l[e];return t?t:l[e]=new RegExp("\\s+"+e+"\\s*=\\s*(...
  function r (line 73) | function r(e,t){var r=e.match(n(t));return r?/^\s*(.*?)\s*$/.exec(r[2])[...
  function o (line 73) | function o(e,t){return new RegExp((t?"^":"")+"</\\s*"+e+"\\s*>","i")}
  function i (line 73) | function i(e,t){for(var n in e)for(var r=t[n]||(t[n]=[]),o=e[n],i=o.leng...
  function a (line 73) | function a(e,t){for(var n=0;n<e.length;n++){var o=e[n];if(!o[0]||o[1].te...
  function l (line 73) | function l(r,i){var s,d=c.token(r,i.htmlState),p=/\btag\b/.test(d);if(p&...
  function r (line 73) | function r(n){if(e.findModeByName){var r=e.findModeByName(n);r&&(n=r.mim...
  function o (line 73) | function o(e,t,n){return t.f=t.inline=n,n(e,t)}
  function i (line 73) | function i(e,t,n){return t.f=t.block=n,n(e,t)}
  function a (line 73) | function a(e){return!e||!/\S/.test(e.string)}
  function s (line 73) | function s(t){if(t.linkTitle=!1,t.linkHref=!1,t.linkText=!1,t.em=!1,t.st...
  function l (line 73) | function l(t,i){var s=t.column()===i.indentation,l=a(i.prevLine.stream),...
  function c (line 73) | function c(t,n){var r=v.token(t,n.htmlState);if(!b){var o=e.innerMode(v,...
  function u (line 73) | function u(e,t){var r=t.listStack[t.listStack.length-1]||0,o=t.indentati...
  function d (line 73) | function d(e){var t=[];if(e.formatting){t.push(y.formatting),"string"==t...
  function p (line 73) | function p(e,t){return e.match(D,!0)?d(t):void 0}
  function h (line 73) | function h(t,r){var o=r.text(t,r);if("undefined"!=typeof o)return o;if(r...
  function g (line 73) | function g(e,t){var r=e.next();if(">"===r){t.f=t.inline=h,n.highlightFor...
  function f (line 73) | function f(e,t){if(e.eatSpace())return null;var r=e.next();return"("===r...
  function m (line 73) | function m(e){return function(t,r){var o=t.next();if(o===e){r.f=r.inline...
  function A (line 73) | function A(e,t){return e.match(/^([^\]\\]|\\.)*\]:/,!1)?(t.f=M,e.next(),...
  function M (line 73) | function M(e,t){if(e.match("]:",!0)){t.f=t.inline=w,n.highlightFormattin...
  function w (line 73) | function w(e,t){return e.eatSpace()?null:(e.match(/^[^\s]+/,!0),void 0==...
  function t (line 74) | function t(t,n,r){var o,i=t.getWrapperElement();return o=i.appendChild(d...
  function n (line 74) | function n(e,t){e.state.currentNotificationClose&&e.state.currentNotific...
  function a (line 74) | function a(t){if("string"==typeof t)d.value=t;else{if(c)return;c=!0,e.rm...
  function a (line 74) | function a(){c||(c=!0,e.rmClass(s.parentNode,"dialog-opened"),s.parentNo...
  function i (line 74) | function i(){l||(l=!0,clearTimeout(a),e.rmClass(s.parentNode,"dialog-ope...
  function t (line 74) | function t(e){var t=e.flags;return null!=t?t:(e.ignoreCase?"i":"")+(e.gl...
  function n (line 74) | function n(e,n){for(var r=t(e),o=r,i=0;i<n.length;i++)-1==o.indexOf(n.ch...
  function r (line 74) | function r(e){return/\\s|\\n|\n|\\W|\\D|\[\^/.test(e.source)}
  function o (line 74) | function o(e,t,r){t=n(t,"g");for(var o=r.line,i=r.ch,a=e.lastLine();a>=o...
  function i (line 74) | function i(e,t,i){if(!r(t))return o(e,t,i);t=n(t,"gm");for(var a,s=1,l=i...
  function a (line 74) | function a(e,t,n){for(var r,o=0;o<=e.length;){t.lastIndex=o;var i=t.exec...
  function s (line 74) | function s(e,t,r){t=n(t,"g");for(var o=r.line,i=r.ch,s=e.firstLine();o>=...
  function l (line 74) | function l(e,t,o){if(!r(t))return s(e,t,o);t=n(t,"gm");for(var i,l=1,c=e...
  function c (line 74) | function c(e,t,n,r){if(e.length==t.length)return n;for(var o=0,i=n+Math....
  function u (line 74) | function u(e,t,n,r){if(!t.length)return null;var o=r?h:g,i=o(t).split(/\...
  function d (line 74) | function d(e,t,n,r){if(!t.length)return null;var o=r?h:g,i=o(t).split(/\...
  function p (line 74) | function p(e,t,r,a){this.atOccurrence=!1,this.afterEmptyMatch=!1,this.do...
  function t (line 74) | function t(e,t){return"string"==typeof e?e=new RegExp(e.replace(/[\-\[\]...
  function n (line 74) | function n(){this.posFrom=this.posTo=this.lastQuery=this.query=null,this...
  function r (line 74) | function r(e){return e.state.search||(e.state.search=new n)}
  function o (line 74) | function o(e){return"string"==typeof e&&e==e.toLowerCase()}
  function i (line 74) | function i(e,t,n){return e.getSearchCursor(t,n,{caseFold:o(t),multiline:...
  function a (line 74) | function a(e,t,n,r,o){e.openDialog(t,r,{value:n,selectValueOnOpen:!0,clo...
  function s (line 74) | function s(e,t,n,r,o){e.openDialog?e.openDialog(t,o,{value:r,selectValue...
  function l (line 74) | function l(e,t,n,r){e.openConfirm?e.openConfirm(t,r):confirm(n)&&r[0]()}
  function c (line 74) | function c(e){return e.replace(/\\([nrt\\])/g,function(e,t){return"n"==t...
  function u (line 74) | function u(e){var t=e.match(/^\/(.*)\/([a-z]*)$/);if(t)try{e=new RegExp(...
  function d (line 74) | function d(e,n,r){n.queryText=r,n.query=u(r),e.removeOverlay(n.overlay,o...
  function p (line 74) | function p(t,n,o,i){var l=r(t);if(l.query)return h(t,n);var c=t.getSelec...
  function h (line 74) | function h(t,n,o){t.operation(function(){var a=r(t),s=i(t,a.query,n?a.po...
  function g (line 74) | function g(e){e.operation(function(){var t=r(e);t.lastQuery=t.query,t.qu...
  function f (line 74) | function f(e,t){var n=e?document.createElement(e):document.createDocumen...
  function m (line 74) | function m(e){var t=f("label",{className:"CodeMirror-search-label"},e.ph...
  function A (line 74) | function A(e){return f("",null," ",f("input",{type:"text",style:"width: ...
  function M (line 74) | function M(e){return f("",null,f("span",{className:"CodeMirror-search-la...
  function w (line 74) | function w(e){return f("",null,f("span",{className:"CodeMirror-search-la...
  function v (line 74) | function v(e,t,n){e.operation(function(){for(var r=i(e,t);r.findNext();)...
  function b (line 74) | function b(e,t){if(!e.getOption("readOnly")){var n=e.getSelection()||r(e...
  function t (line 74) | function t(e,t){function n(e){clearTimeout(r.doRedraw),r.doRedraw=setTim...
  function t (line 74) | function t(e,t){if(l!=e.line){l=e.line,c=n.getLineHandle(e.line);var r=n...
  function t (line 74) | function t(e,t,n,r){this.cm=e,this.options=r;var o={listenForChanges:!1}...
  function n (line 74) | function n(e,t,n){return t>=e?e:Math.max(t,e+n)}
  function t (line 74) | function t(t,o,i,a){function s(e){var n=l(t,o);if(!n||n.to.line-n.from.l...
  function n (line 74) | function n(e,t,n){var o=r(e,t,"widget");if("function"==typeof o&&(o=o(n....
  function r (line 74) | function r(e,t,n){if(t&&void 0!==t[n])return t[n];var r=e.options.foldOp...
  function t (line 74) | function t(e){this.options=e,this.from=this.to=0}
  function n (line 74) | function n(e){return e===!0&&(e={}),null==e.gutter&&(e.gutter="CodeMirro...
  function r (line 74) | function r(e,t){for(var n=e.findMarks(h(t,0),h(t+1,0)),r=0;r<n.length;++...
  function o (line 74) | function o(e){if("string"==typeof e){var t=document.createElement("div")...
  function i (line 74) | function i(e,t,n){var i=e.state.foldGutter.options,s=t-1,l=e.foldOption(...
  function a (line 74) | function a(e){return new RegExp("(^|\\s)"+e+"(?:$|\\s)\\s*")}
  function s (line 74) | function s(e){var t=e.getViewport(),n=e.state.foldGutter;n&&(e.operation...
  function l (line 74) | function l(e,t,n){var o=e.state.foldGutter;if(o){var i=o.options;if(n==i...
  function c (line 74) | function c(e,t){"mode"==t&&u(e)}
  function u (line 74) | function u(e){var t=e.state.foldGutter;if(t){var n=t.options;t.from=t.to...
  function d (line 74) | function d(e){var t=e.state.foldGutter;if(t){var n=t.options;clearTimeou...
  function p (line 74) | function p(e,t){var n=e.state.foldGutter;if(n){var r=t.line;r>=n.from&&r...
  function t (line 74) | function t(t){return function(n,r){function o(t){for(var o,i=r.ch,l=0;;)...
  function r (line 74) | function r(n){if(n<t.firstLine()||n>t.lastLine())return null;var r=t.get...
  function r (line 74) | function r(n){if(n<t.firstLine()||n>t.lastLine())return null;var r=t.get...
  function r (line 74) | function r(e,t){var n=t&&1===t.length&&t[0];return n&&(n.text||n)===e}
  function o (line 74) | function o(){var e=B.rulesModal,t=e&&e.getSelectedList(),n=e&&e.getActiv...
  function i (line 75) | function i(e,t){var n=e.moduleName,r=t&&t.hintUrl||e.hintUrl||"",o="plug...
  function a (line 75) | function a(e){if(z)return[];var t=U.getAllRules();if(!e)return t;e=e.toL...
  function s (line 75) | function s(e){var t=e.indexOf("<"),n=-1===t?e:e.substring(0,t);return{te...
  function l (line 75) | function l(e,t,n){if(e=e.toLowerCase(),/[:=]/.test(e))return[];var r=[],...
  function c (line 75) | function c(e,t,n){var r=function(e){return s(t+e)};if(!e)return n.map(r)...
  function u (line 75) | function u(e){e=e.substring(1);try{var t=window.parent.getAtValueListFor...
  function d (line 75) | function d(e,t){return{text:e,displayText:e+"("+("pipe"===t?"pipe":"sni"...
  function p (line 75) | function p(e,t){var n,r=e;if(t?(e=e.substring(t.length+3),n=U.getAllPlug...
  function h (line 75) | function h(e,t){try{var n=window.parent.getAtHelpUrlForWhistle;if("funct...
  function g (line 75) | function g(e,t){return"string"!=typeof t&&(t=""),t||e.homepage||R.getDoc...
  function f (line 75) | function f(e,t,n,r){return n?e+(r?".":"=")+t:e+"://"+t}
  function m (line 75) | function m(e,t,n,o,i,a,s,l){if(C=[],q={},I=null,E=0,!e||a.hasDestroyed||...
  function A (line 75) | function A(e){return"includeFilter://"===e||"excludeFilter://"===e}
  function M (line 75) | function M(e){if(e){if(!e.indexOf("pipe://"))return"pipe";if(!e.indexOf(...
  function w (line 75) | function w(e){var t=e.length,n=1===t?e[0]:"";return n?0===n.indexOf("hea...
  function v (line 75) | function v(e,t){return(!t||t())&&setTimeout(function(){e.state.completio...
  function b (line 75) | function b(e){Ae=null;var t,n=k("li.CodeMirror-hint-active");if(n.is(":v...
  function t (line 75) | function t(e,t){if(this.cm=e,this.options=t,this.widget=null,this.deboun...
  function n (line 75) | function n(e,t,n){var r=e.options.hintOptions,o={};for(var i in g)o[i]=g...
  function r (line 75) | function r(e){return"string"==typeof e?e:e.text}
  function o (line 75) | function o(e,t){function n(e,n){var o;o="string"!=typeof n?function(e){r...
  function i (line 75) | function i(e,t){for(;t&&t!=e;){if("LI"===t.nodeName.toUpperCase()&&t.par...
  function a (line 75) | function a(t,n){this.id="cm-complete-"+Math.floor(Math.random(1e6)),this...
  function s (line 75) | function s(e,t){if(!e.somethingSelected())return t;for(var n=[],r=0;r<t....
  function l (line 75) | function l(e,t,n,r){if(e.async)e(t,r,n);else{var o=e(t,n);o&&o.then?o.th...
  function c (line 75) | function c(t,n){var r,o=t.getHelpers(n,"hint");if(o.length){var i=functi...
  function r (line 75) | function r(e){e=e.substring(e.indexOf(".")+1);for(var t=0,n=m.length;n>t...
  function r (line 75) | function r(e){return e&&(0==e||e>65535)}
  function e (line 75) | function e(e){var t;if(g.test(e)&&(e=RegExp.$1,t=RegExp.$2,r(t)))return!...
  function t (line 75) | function t(e){return/^x?hosts?:\/\//.test(e)}
  function n (line 75) | function n(e){return/^head:\/\//.test(e)}
  function o (line 75) | function o(e){return/^weinre:\/\//.test(e)}
  function i (line 75) | function i(e){return/^(?:referer|auth|ua|forwardedFor|reqCookies|reqDela...
  function a (line 75) | function a(e){return/^(?:resScript|frameScript|resRules|responseFor|resC...
  function m (line 75) | function m(e){return/^(?:https?|wss?|tunnel):\/\//i.test(e)}
  function A (line 75) | function A(e){return/^[\w\.-]+:\/\//i.test(e)}
  function M (line 75) | function M(e){return e=e.substring(0,e.indexOf(":")),-1==s.indexOf(e)&&"...
  function w (line 75) | function w(e){return e=e.substring(0,e.indexOf(":")),-1==l.indexOf(e)}
  function v (line 75) | function v(e){return/^\/[^/](.*)\/i?$/.test(e)||/^\$/.test(e)}
  function b (line 75) | function b(e){return/^(?:urlParams|params|reqMerge|urlReplace|pathReplac...
  function y (line 75) | function y(e){return/^log:\/\//.test(e)}
  function x (line 75) | function x(e){return/^style:\/\//.test(e)}
  function T (line 75) | function T(e){return/^(?:excludeFilter|filter):\/\//.test(e)}
  function C (line 75) | function C(e){return/^lineProps:\/\//.test(e)}
  function N (line 75) | function N(e){return/^(?:pipe|sniCallback):\/\//.test(e)||/^(?:plugin|wh...
  function I (line 75) | function I(e){return/^(?:rules?(?:File|Script)|reqScript|reqRules):\/\//...
  function E (line 75) | function E(e){return/^disable:\/\//.test(e)}
  function D (line 75) | function D(e){return/^(?:cipher|tlsOptions):\/\//.test(e)}
  function S (line 75) | function S(e){return/^(?:ignore|skip):\/\//.test(e)}
  function L (line 75) | function L(e){return/^(?:includeFilter|enable):\/\//.test(e)}
  function k (line 75) | function k(e){return/^delete:\/\//.test(e)}
  function j (line 75) | function j(e){return/^headerReplace:\/\//.test(e)}
  function U (line 75) | function U(e){return/^x?(?:proxy|https?-proxy|http2https-proxy|https2htt...
  function B (line 75) | function B(e){return/^x?socks:\/\//.test(e)}
  function R (line 75) | function R(e){return/^pac:\/\//.test(e)}
  function z (line 75) | function z(e){return/^[a-z]:(?:\\|\/(?!\/))/i.test(e)||/^\/[^/]/.test(e)}
  function Q (line 75) | function Q(e){return/^:\d{1,5}$/.test(e)}
  function O (line 75) | function O(e){if(!/^(?:\$?(?:https?:|wss?:|tunnel:)?\/\/)?([^/?]+)/.test...
  function H (line 75) | function H(e){return f.test(e)}
  function F (line 75) | function F(e){return/^\^/.test(e)||c.test(e)}
  function r (line 76) | function r(e){if(e!==s)try{document.body.removeChild(e.iframe),e.destroy...
  function o (line 76) | function o(e){try{var t=e.location.pathname.substring(1)+e.location.sear...
  function i (line 76) | function i(e){function t(t){try{"function"==typeof e.onWhistleContextMen...
  function a (line 76) | function a(){var e=Object.keys(g),t=e.length;if(!(d>t)){for(var n=g[e[0]...
  function r (line 76) | function r(){return++g>100&&(g=0),g}
  function o (line 76) | function o(e){try{delete window[e]}catch(t){window[e]=void 0}}
  function i (line 76) | function i(e,t,n){var r=document.createElement("div");document.body.appe...
  function a (line 76) | function a(e,t){return e&&"string"==typeof e?e.replace(/\s(on[a-z]+=)"([...
  function s (line 76) | function s(e,t,n){var r=e.find(".modal-content>.modal-"+n+":first");null...
  function l (line 76) | function l(e,t,n){t=t||"";var r=t.title,o=a(t.body,n),i=a(t.footer,n),l=...
  function r (line 76) | function r(e){return"string"!=typeof e&&(e.type=e.type||e.method),e}
  function o (line 76) | function o(e){if(e)try{for(var t=e.location.pathname.split("/"),n=t.leng...
  function i (line 76) | function i(e,t){var n=o(e),i={updateUI:function(){h.trigger("updateUIThr...
  function r (line 76) | function r(e,t,n,r,a){var s=[].slice.call(arguments,1),l=s.length,c="fun...
  function r (line 76) | function r(e,t){for(var n=e.size,r=M.getPositions(t),o=0;o<r.length;o++)...
  function o (line 76) | function o(e){for(var t=e.size,n=8;t-8>n;n++){var r=n%2===0;e.set(n,6,r,...
  function i (line 76) | function i(e,t){for(var n=A.getPositions(t),r=0;r<n.length;r++)for(var o...
  function a (line 76) | function a(e,t){for(var n,r,o,i=e.size,a=y.getEncodedBits(t),s=0;18>s;s+...
  function s (line 76) | function s(e,t,n){var r,o,i=e.size,a=x.getEncodedBits(t,n);for(r=0;15>r;...
  function l (line 76) | function l(e,t){for(var n=e.size,r=-1,o=n-1,i=7,a=0,s=n-1;s>0;s-=2)for(6...
  function c (line 76) | function c(e,t,n){var r=new f;n.forEach(function(t){r.put(t.mode.bit,4),...
  function u (line 76) | function u(e,t,n){for(var r=h.getSymbolTotalCodewords(t),o=v.getTotalCod...
  function d (line 76) | function d(e,t,n,u){var d;if(N(e))d=C.fromArray(e);else{if("string"!=typ...
  function r (line 76) | function r(){try{var e=new Uint8Array(1);return e.__proto__={__proto__:U...
  function t (line 76) | function t(e,n,r){return t.TYPED_ARRAY_SUPPORT||this instanceof t?"numbe...
  function o (line 76) | function o(e){if(e>=M)throw new RangeError("Attempt to allocate Buffer l...
  function i (line 76) | function i(e){return e!==e}
  function a (line 76) | function a(e,n){var r;return t.TYPED_ARRAY_SUPPORT?(r=new Uint8Array(n),...
  function s (line 76) | function s(e,n){var r=a(e,0>n?0:0|o(n));if(!t.TYPED_ARRAY_SUPPORT)for(va...
  function l (line 76) | function l(e,t){var n=0|h(t),r=a(e,n),o=r.write(t);return o!==n&&(r=r.sl...
  function c (line 76) | function c(e,t){for(var n=t.length<0?0:0|o(t.length),r=a(e,n),i=0;n>i;i+...
  function u (line 76) | function u(e,n,r,o){if(0>r||n.byteLength<r)throw new RangeError("'offset...
  function d (line 76) | function d(e,n){if(t.isBuffer(n)){var r=0|o(n.length),s=a(e,r);return 0=...
  function p (line 76) | function p(e,t){t=t||1/0;for(var n,r=e.length,o=null,i=[],a=0;r>a;++a){i...
  function h (line 76) | function h(e){if(t.isBuffer(e))return e.length;if("undefined"!=typeof Ar...
  function g (line 76) | function g(e,t,n,r){for(var o=0;r>o&&!(o+n>=t.length||o>=e.length);++o)t...
  function f (line 76) | function f(e,t,n,r){return g(p(t,e.length-n),e,n,r)}
  function m (line 76) | function m(e,t,n,r){if("number"==typeof t)throw new TypeError('"value" a...
  function o (line 82) | function o(){try{var e=new Uint8Array(1);return e.__proto__={__proto__:U...
  function i (line 82) | function i(){return e.TYPED_ARRAY_SUPPORT?2147483647:1073741823}
  function a (line 82) | function a(t,n){if(i()<n)throw new RangeError("Invalid typed array lengt...
  function e (line 82) | function e(t,n,r){if(!(e.TYPED_ARRAY_SUPPORT||this instanceof e))return ...
  function s (line 82) | function s(e,t,n,r){if("number"==typeof t)throw new TypeError('"value" a...
  function l (line 82) | function l(e){if("number"!=typeof e)throw new TypeError('"size" argument...
  function c (line 82) | function c(e,t,n,r){return l(t),0>=t?a(e,t):void 0!==n?"string"==typeof ...
  function u (line 82) | function u(t,n){if(l(n),t=a(t,0>n?0:0|f(n)),!e.TYPED_ARRAY_SUPPORT)for(v...
  function d (line 82) | function d(t,n,r){if(("string"!=typeof r||""===r)&&(r="utf8"),!e.isEncod...
  function p (line 82) | function p(e,t){var n=t.length<0?0:0|f(t.length);e=a(e,n);for(var r=0;n>...
  function h (line 82) | function h(t,n,r,o){if(n.byteLength,0>r||n.byteLength<r)throw new RangeE...
  function g (line 82) | function g(t,n){if(e.isBuffer(n)){var r=0|f(n.length);return t=a(t,r),0=...
  function f (line 82) | function f(e){if(e>=i())throw new RangeError("Attempt to allocate Buffer...
  function m (line 82) | function m(t){return+t!=t&&(t=0),e.alloc(+t)}
  function A (line 82) | function A(t,n){if(e.isBuffer(t))return t.length;if("undefined"!=typeof ...
  function M (line 82) | function M(e,t,n){var r=!1;if((void 0===t||0>t)&&(t=0),t>this.length)ret...
  function w (line 82) | function w(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}
  function v (line 82) | function v(t,n,r,o,i){if(0===t.length)return-1;if("string"==typeof r?(o=...
  function b (line 82) | function b(e,t,n,r,o){function i(e,t){return 1===a?e[t]:e.readUInt16BE(t...
  function y (line 82) | function y(e,t,n,r){n=Number(n)||0;var o=e.length-n;r?(r=Number(r),r>o&&...
  function x (line 82) | function x(e,t,n,r){return q(G(t,e.length-n),e,n,r)}
  function T (line 82) | function T(e,t,n,r){return q(W(t),e,n,r)}
  function C (line 82) | function C(e,t,n,r){return T(e,t,n,r)}
  function N (line 82) | function N(e,t,n,r){return q(_(t),e,n,r)}
  function I (line 82) | function I(e,t,n,r){return q(X(t,e.length-n),e,n,r)}
  function E (line 82) | function E(e,t,n){return 0===t&&n===e.length?K.fromByteArray(e):K.fromBy...
  function D (line 82) | function D(e,t,n){n=Math.min(e.length,n);for(var r=[],o=t;n>o;){var i=e[...
  function S (line 82) | function S(e){var t=e.length;if(ee>=t)return String.fromCharCode.apply(S...
  function L (line 82) | function L(e,t,n){var r="";n=Math.min(e.length,n);for(var o=t;n>o;++o)r+...
  function k (line 82) | function k(e,t,n){var r="";n=Math.min(e.length,n);for(var o=t;n>o;++o)r+...
  function j (line 82) | function j(e,t,n){var r=e.length;(!t||0>t)&&(t=0),(!n||0>n||n>r)&&(n=r);...
  function U (line 82) | function U(e,t,n){for(var r=e.slice(t,n),o="",i=0;i<r.length;i+=2)o+=Str...
  function B (line 82) | function B(e,t,n){if(e%1!==0||0>e)throw new RangeError("offset is not ui...
  function R (line 82) | function R(t,n,r,o,i,a){if(!e.isBuffer(t))throw new TypeError('"buffer" ...
  function z (line 82) | function z(e,t,n,r){0>t&&(t=65535+t+1);for(var o=0,i=Math.min(e.length-n...
  function Q (line 82) | function Q(e,t,n,r){0>t&&(t=4294967295+t+1);for(var o=0,i=Math.min(e.len...
  function O (line 82) | function O(e,t,n,r,o,i){if(n+r>e.length)throw new RangeError("Index out ...
  function H (line 82) | function H(e,t,n,r,o){return o||O(e,t,n,4,3.4028234663852886e38,-3.40282...
  function F (line 82) | function F(e,t,n,r,o){return o||O(e,t,n,8,1.7976931348623157e308,-1.7976...
  function V (line 82) | function V(e){if(e=P(e).replace(te,""),e.length<2)return"";for(;e.length...
  function P (line 82) | function P(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}
  function Y (line 82) | function Y(e){return 16>e?"0"+e.toString(16):e.toString(16)}
  function G (line 82) | function G(e,t){t=t||1/0;for(var n,r=e.length,o=null,i=[],a=0;r>a;++a){i...
  function W (line 82) | function W(e){for(var t=[],n=0;n<e.length;++n)t.push(255&e.charCodeAt(n)...
  function X (line 82) | function X(e,t){for(var n,r,o,i=[],a=0;a<e.length&&!((t-=2)<0);++a)n=e.c...
  function _ (line 82) | function _(e){return K.toByteArray(V(e))}
  function q (line 82) | function q(e,t,n,r){for(var o=0;r>o&&!(o+n>=t.length||o>=e.length);++o)t...
  function J (line 82) | function J(e){return e!==e}
  function n (line 83) | function n(e){if("string"!=typeof e)throw new Error("Param is not a stri...
  function n (line 83) | function n(){this.buffer=[],this.length=0}
  function r (line 83) | function r(e){if(!e||1>e)throw new Error("BitMatrix size must be defined...
  function n (line 83) | function n(e,n,r){switch(e){case t.Patterns.PATTERN000:return(n+r)%2===0...
  function r (line 83) | function r(e){this.genPoly=void 0,this.degree=e,this.degree&&this.initia...
  function r (line 83) | function r(e,n,r){for(var o=1;40>=o;o++)if(n<=t.getCapacity(o,r,e))retur...
  function o (line 83) | function o(e,t){return u.getCharCountIndicator(e,t)+4}
  function i (line 83) | function i(e,t){var n=0;return e.forEach(function(e){var r=o(e.mode,t);n...
  function a (line 83) | function a(e,n){for(var r=1;40>=r;r++){var o=i(e,r);if(o<=t.getCapacity(...
  function r (line 83) | function r(e){if("string"!=typeof e)throw new Error("Param is not a stri...
  function r (line 83) | function r(e){return unescape(encodeURIComponent(e)).length}
  function o (line 83) | function o(e,t,n){for(var r,o=[];null!==(r=e.exec(n));)o.push({data:r[0]...
  function i (line 83) | function i(e){var t,n,r=o(m.NUMERIC,d.NUMERIC,e),i=o(m.ALPHANUMERIC,d.AL...
  function a (line 83) | function a(e,t){switch(t){case d.NUMERIC:return p.getBitsLength(e);case ...
  function s (line 83) | function s(e){return e.reduce(function(e,t){var n=e.length-1>=0?e[e.leng...
  function l (line 83) | function l(e){for(var t=[],n=0;n<e.length;n++){var o=e[n];switch(o.mode)...
  function c (line 83) | function c(e,t){for(var n={},r={start:{}},o=["start"],i=0;i<e.length;i++...
  function u (line 83) | function u(e,t){var n,r=d.getBestModeForData(e);if(n=d.from(t,r),n!==d.B...
  function r (line 83) | function r(e){this.mode=o.NUMERIC,this.data=e.toString()}
  function r (line 83) | function r(e){this.mode=o.ALPHANUMERIC,this.data=e}
  function r (line 83) | function r(e){this.mode=i.BYTE,this.data=new o(e)}
  function r (line 83) | function r(e){this.mode=o.KANJI,this.data=e}
  function r (line 83) | function r(e,t,n){e.clearRect(0,0,t.width,t.height),t.style||(t.style={}...
  function o (line 83) | function o(){try{return document.createElement("canvas")}catch(e){throw ...
  function n (line 83) | function n(e){if("string"!=typeof e)throw new Error("Color should be def...
  function r (line 83) | function r(e,t){var n=e.a/255,r=t+'="'+e.hex+'"';return 1>n?r+" "+t+'-op...
  function o (line 83) | function o(e,t,n){var r=e+t;return"undefined"!=typeof n&&(r+=" "+n),r}
  function i (line 83) | function i(e,t,n){for(var r="",i=0,a=!1,s=0,l=0;l<e.length;l++){var c=Ma...
  function r (line 83) | function r(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t<e.len...
  function o (line 83) | function o(e){return p.test(e)||u.test(e)||d.test(e)||h.test(e)}
  function i (line 83) | function i(e){for(var t=-1,n=0,r=e.length;r>n;n++){var i=e[n];if(o(i))re...
  function a (line 83) | function a(e){var t=[];return e=e.filter(function(e){return m.test(e)||f...
  function r (line 83) | function r(e){try{return decodeURIComponent(e)}catch(t){}return e}
  function r (line 83) | function r(e,t){var n=t?e.indexOf(t):-1,r="";return-1!==n&&(r=e.substrin...
  function r (line 84) | function r(e){return e&&e.__esModule?e:{"default":e}}
  function o (line 84) | function o(e,t){var n={getArrowStyle:"arrow",getListStyle:"nestedNodeChi...
  function i (line 84) | function i(e){var t=o(e.theme,e);return e.invertTheme&&("string"==typeof...
  function t (line 84) | function t(n){g["default"](this,t);var r,o,s,l=[{name:"Copy"},{name:"Cop...
  function r (line 84) | function r(e){return e&&e.__esModule?e:{"default":e}}
  function r (line 84) | function r(e){return e&&e.__esModule?e:{"default":e}}
  function r (line 84) | function r(e){return e&&e.__esModule?e:{"default":e}}
  function r (line 84) | function r(e){return e&&e.__esModule?e:{"default":e}}
  function r (line 84) | function r(e){return e&&e.__esModule?e:{"default":e}}
  function r (line 84) | function r(e){return e&&e.__esModule?e:{"default":e}}
  function o (line 84) | function o(e){var t=Object.prototype.toString.call(e).slice(8,-1);return...
  function r (line 84) | function r(e){return e&&e.__esModule?e:{"default":e}}
  function o (line 84) | function o(e){var t=u["default"](e).length;return t+" "+(1!==t?"keys":"k...
  function r (line 84) | function r(e){return e&&e.__esModule?e:{"default":e}}
  function o (line 84) | function o(e,t,n){var r=e.nodeType,i=e.data,a=e.collectionLimit,s=e.circ...
  function i (line 84) | function i(e){var t=e.shouldExpandNode&&!e.isCircular?e.shouldExpandNode...
  function t (line 84) | function t(n){d["default"](this,t);var r=h["default"](this,e.call(this,n...
  function r (line 84) | function r(e){return e&&e.__esModule?e:{"default":e}}
  function r (line 84) | function r(e){return e&&e.__esModule?e:{"default":e}}
  function o (line 84) | function o(e,t){return"Object"===e?g["default"](t).length:"Array"===e?t....
  function i (line 84) | function i(e){return"function"==typeof e.set}
  function a (line 84) | function a(e,t,n){var r=arguments.length>3&&void 0!==arguments[3]?argume...
  function s (line 85) | function s(e,t,n){for(var r=[];t-e>n*n;)n*=n;for(var o=e;t>=o;o+=n)r.pus...
  function l (line 85) | function l(e,t,n,r){var i=arguments.length>4&&void 0!==arguments[4]?argu...
  function r (line 85) | function r(e){return e&&e.__esModule?e:{"default":e}}
  function t (line 85) | function t(n){s["default"](this,t);var r=c["default"](this,e.call(this,n...
  function r (line 85) | function r(e){return e&&e.__esModule?e:{"default":e}}
  function o (line 85) | function o(e){return e.length+" "+(1!==e.length?"items":"item")}
  function r (line 85) | function r(e){return e&&e.__esModule?e:{"default":e}}
  function o (line 85) | function o(e,t){var n=0,r=!1;if(h["default"](e.size))n=e.size;else for(v...
  function i (line 85) | function i(e){var t=c["default"](e,[]);return f["default"].createElement...
  function r (line 85) | function r(e){return e&&e.__esModule?e:{"default":e}}
  function r (line 85) | function r(e){return e&&e.__esModule?e:{"default":e}}
  function r (line 85) | function r(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n ...
  function o (line 85) | function o(e){return e&&e.__esModule?e:{"default":e}}
  function r (line 85) | function r(e){return e&&e.__esModule?e:{"default":e}}
  function e (line 85) | function e(e,t){var n=[],r=!0,o=!1,i=void 0;try{for(var a,l=s["default"]...
  function n (line 85) | function n(e,t,n){switch(n.length){case 0:return e.call(t);case 1:return...
  function r (line 85) | function r(e,t){for(var n=-1,r=e?e.length:0;++n<r&&t(e[n],n,e)!==!1;);re...
  function o (line 85) | function o(e,t){var n=e?e.length:0;return!!n&&a(e,t,0)>-1}
  function i (line 85) | function i(e,t,n,r){for(var o=e.length,i=n+(r?1:-1);r?i--:++i<o;)if(t(e[...
  function a (line 85) | function a(e,t,n){if(t!==t)return i(e,s,n);for(var r=n-1,o=e.length;++r<...
  function s (line 85) | function s(e){return e!==e}
  function l (line 85) | function l(e,t){for(var n=e.length,r=0;n--;)e[n]===t&&r++;return r}
  function c (line 85) | function c(e,t){return null==e?void 0:e[t]}
  function u (line 85) | function u(e){var t=!1;if(null!=e&&"function"!=typeof e.toString)try{t=!...
  function d (line 85) | function d(e,t){for(var n=-1,r=e.length,o=0,i=[];++n<r;){var a=e[n];(a==...
  function p (line 85) | function p(e){return B(e)?Le(e):{}}
  function h (line 85) | function h(e){if(!B(e)||D(e))return!1;var t=U(e)||u(e)?Se:me;return t.te...
  function g (line 85) | function g(e,t,n,r){for(var o=-1,i=e.length,a=n.length,s=-1,l=t.length,c...
  function f (line 85) | function f(e,t,n,r){for(var o=-1,i=e.length,a=-1,s=n.length,l=-1,c=t.len...
  function m (line 85) | function m(e,t){var n=-1,r=e.length;for(t||(t=Array(r));++n<r;)t[n]=e[n]...
  function A (line 85) | function A(e,t,n){function r(){var t=this&&this!==ye&&this instanceof r?...
  function M (line 85) | function M(e){return function(){var t=arguments;switch(t.length){case 0:...
  function w (line 85) | function w(e,t,r){function o(){for(var a=arguments.length,s=Array(a),l=a...
  function v (line 85) | function v(e,t,n,r,o,i,a,s,c,u){function p(){for(var C=arguments.length,...
  function b (line 85) | function b(e,t,r,o){function i(){for(var t=-1,l=arguments.length,c=-1,u=...
  function y (line 85) | function y(e,t,n,r,o,i,a,s,l,c){var u=t&_,d=u?a:void 0,p=u?void 0:a,h=u?...
  function x (line 85) | function x(e,t,n,r,o,i,a,s){var l=t&W;if(!l&&"function"!=typeof e)throw ...
  function T (line 85) | function T(e){var t=e;return t.placeholder}
  function C (line 85) | function C(e,t){var n=c(e,t);return h(n)?n:void 0}
  function N (line 85) | function N(e){var t=e.match(pe);return t?t[1].split(he):[]}
  function I (line 85) | function I(e,t){var n=t.length,r=n-1;return t[r]=(n>1?"& ":"")+t[r],t=t....
  function E (line 85) | function E(e,t){return t=null==t?ne:t,!!t&&("number"==typeof e||Me.test(...
  function D (line 85) | function D(e){return!!Ne&&Ne in e}
  function S (line 85) | function S(e,t){for(var n=e.length,r=je(t.length,n),o=m(e);r--;){var i=t...
  function L (line 85) | function L(e){if(null!=e){try{return Ie.call(e)}catch(t){}try{return e+"...
  function k (line 85) | function k(e,t){return r(ie,function(n){var r="_."+n[0];t&n[1]&&!o(e,r)&...
  function j (line 85) | function j(e,t,n){t=n?void 0:t;var r=x(e,_,void 0,void 0,void 0,void 0,v...
  function U (line 85) | function U(e){var t=B(e)?De.call(e):"";return t==ae||t==se}
  function B (line 85) | function B(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}
  function R (line 85) | function R(e){return!!e&&"object"==typeof e}
  function z (line 85) | function z(e){return"symbol"==typeof e||R(e)&&De.call(e)==le}
  function Q (line 85) | function Q(e){if(!e)return 0===e?e:0;if(e=H(e),e===te||e===-te){var t=0>...
  function O (line 85) | function O(e){var t=Q(e),n=t%1;return t===t?n?t-n:t:0}
  function H (line 85) | function H(e){if("number"==typeof e)return e;if(z(e))return oe;if(B(e)){...
  function F (line 85) | function F(e){return function(){return e}}
  function V (line 85) | function V(e){return e}
  function r (line 85) | function r(e){return e&&e.__esModule?e["default"]:e}
  function r (line 86) | function r(e){var t=Math.round(i(e,0,255)),n=t.toString(16);return 1==n....
  function o (line 86) | function o(e){var t=4===e.length?r(255*e[3]):"";return"#"+r(e[0])+r(e[1]...
  function n (line 86) | function n(e,t,n){return Math.min(Math.max(e,t),n)}
  function r (line 86) | function r(e){var t=i(e),n=l(t);return 4===t.length&&n.push(t[3]),n}
  function o (line 86) | function o(e){for(var t in c)if(0===e.indexOf(t))return c[t](e)}
  function r (line 86) | function r(e,t){switch(e=parseFloat(e),t){case 0:return a(e,0,360);case ...
  function o (line 86) | function o(e){return i(e).map(r)}
  function n (line 86) | function n(e){return e.match(r)}
  function n (line 86) | function n(e){for(var t="#",n=1;n<e.length;n++){var r=e.charAt(n);t+=r+r...
  function r (line 86) | function r(e){(4===e.length||5===e.length)&&(e=n(e));var t=[parseInt(e.s...
  function r (line 86) | function r(e,t){return 3>t?-1!=e.indexOf("%")?Math.round(255*a(parseInt(...
  function o (line 86) | function o(e){return i(e).map(r)}
  function n (line 86) | function n(e){var t,n,r,o,i,a=e[0]/360,s=e[1]/100,l=e[2]/100;if(0==s)ret...
  function n (line 86) | function n(e,t,n){switch(n.length){case 0:return e.call(t);case 1:return...
  function r (line 86) | function r(e,t){for(var n=-1,r=t.length,o=e.length;++n<r;)e[o+n]=t[n];re...
  function o (line 86) | function o(e,t,n,i,a){var l=-1,c=e.length;for(n||(n=s),a||(a=[]);++l<c;)...
  function i (line 86) | function i(e,t){return t=D(void 0===t?e.length-1:t,0),function(){for(var...
  function a (line 86) | function a(e){return i(function(t){t=o(t,1);var n=t.length,r=n;for(e&&t....
  function s (line 86) | function s(e){return S(e)||l(e)||!!(E&&e&&e[E])}
  function l (line 86) | function l(e){return u(e)&&T.call(e,"callee")&&(!I.call(e,"callee")||C.c...
  function c (line 86) | function c(e){return null!=e&&p(e.length)&&!d(e)}
  function u (line 86) | function u(e){return g(e)&&c(e)}
  function d (line 86) | function d(e){var t=h(e)?C.call(e):"";return t==M||t==w}
  function p (line 86) | function p(e){return"number"==typeof e&&e>-1&&e%1==0&&m>=e}
  function h (line 86) | function h(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}
  function g (line 86) | function g(e){return!!e&&"object"==typeof e}
  function n (line 86) | function n(e){var t,n,r,o=e[0],i=e[1],a=e[2];return t=1*o+0*i+1.13983*a,...
  function r (line 86) | function r(e){var t=e[0]/255,n=e[1]/255,r=e[2]/255,o=.299*t+.587*n+.114*...
  function r (line 86) | function r(e,t){this.reset(e,t,!0)}
  function o (line 86) | function o(e,t){if(!c.isGroup(t))for(var n=0,r=e.length;r>n;n++)if(c.isG...
  function i (line 86) | function i(e,t,n){if(!e)return!1;var r=this.get(e);if(t=t||"",r)return v...
  function a (line 86) | function a(e,t){return t?!e:e}
  function s (line 86) | function s(e){return!e.hide&&!c.isGroup(e.name)}
  function r (line 86) | function r(e,t){return t=t?m.extend({},t):{},t[e.minWidth?"minWidth":"wi...
  function o (line 86) | function o(e){var t=e.rules;if(!t)return"";var n=t.rule;return n&&(n.isL...
  function i (line 86) | function i(e){return l(e)+" w-req-data-item"+(e.isHttps?" w-tunnel":"")+...
  function a (line 86) | function a(e){return!e.hide}
  function s (line 86) | function s(e){var t=e.parent;return!t||t.expand&&t.pExpand}
  function l (line 86) | function l(e){var t="",n=e.res.headers;switch(M.getContentType(n)){case"...
  function c (line 86) | function c(e){return-1!==e.indexOf("w-error-status")?"ERROR":-1!==e.inde...
  function u (line 86) | function u(e,t){if(-1!==t.indexOf("danger"))return g.createElement(I,{na...
  function d (line 86) | function d(e){e.removeClass("highlight")}
  function o (line 87) | function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a ...
  function i (line 87) | function i(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.en...
  function a (line 87) | function a(e,t,n){return t&&i(e.prototype,t),n&&i(e,n),e}
  function s (line 87) | function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enume...
  function l (line 87) | function l(){return(l=Object.assign||function(e){for(var t=1;t<arguments...
  function c (line 87) | function c(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){va...
  function u (line 87) | function u(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[...
  function d (line 87) | function d(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("S...
  function p (line 87) | function p(e){return(p=Object.setPrototypeOf?Object.getPrototypeOf:funct...
  function h (line 87) | function h(e,t){return(h=Object.setPrototypeOf||function(e,t){return e._...
  function g (line 87) | function g(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)r...
  function f (line 87) | function f(e){if(void 0===e)throw new ReferenceError("this hasn't been i...
  function m (line 87) | function m(e,t){return!t||"object"!=typeof t&&"function"!=typeof t?f(e):t}
  function A (line 87) | function A(e,t){return function(e){return Array.isArray(e)?e:void 0}(e)|...
  function M (line 87) | function M(e){return function(e){if(Array.isArray(e)){for(var t=0,n=new ...
  function w (line 87) | function w(){var e=this.constructor.getDerivedStateFromProps(this.props,...
  function v (line 87) | function v(e){this.setState(function(t){var n=this.constructor.getDerive...
  function b (line 87) | function b(e,t){try{var n=this.props,r=this.state;this.props=e,this.stat...
  function y (line 87) | function y(e){var t=e.prototype;if(!t||!t.isReactComponent)throw new Err...
  function x (line 87) | function x(t,n){var r,o,i,a=void 0!==(r=void 0!==n?n:"undefined"!=typeof...
  function T (line 87) | function T(e,t){return"".concat(e,"-").concat(t)}
  function C (line 87) | function C(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.ca...
  function N (line 87) | function N(e,t){return e(t={exports:{}},t.exports),t.exports}
  function I (line 87) | function I(e,t,n,r,o){for(var i in e)if(Ee(e,i)){var a;try{if("function"...
  function E (line 87) | function E(){return null}
  function D (line 87) | function D(e,t){function n(e,t){return e===t?0!==e||1/e==1/t:e!=e&&t!=t}...
  function S (line 88) | function S(e){var t,n,r="";if(e)if("object"==typeof e)if(e.push)for(t=0;...
  function L (line 88) | function L(){for(var e,t=0,n="";t<arguments.length;)(e=S(arguments[t++])...
  function k (line 88) | function k(e){var t=!(0<arguments.length&&void 0!==e)||e,n={};return fun...
  function j (line 88) | function j(e){if((!ke&&0!==ke||e)&&Ue){var t=document.createElement("div...
  function U (line 88) | function U(e){var t=e.align,n=void 0===t?"auto":t,r=e.cellOffset,o=e.cel...
  function B (line 88) | function B(e){var t=e.cellCount,n=e.cellSize,r=e.computeMetadataCallback...
  function R (line 88) | function R(e){var t=e.cellCount,n=e.overscanCellsCount,r=e.scrollDirecti...
  function z (line 88) | function z(e){var t=e.cellSize,n=e.cellSizeAndPositionManager,r=e.previo...
  function Q (line 88) | function Q(e){for(var t=e.cellCache,n=e.cellRenderer,r=e.columnSizeAndPo...
  function O (line 88) | function O(e,t){t&&(t.type&&t.type.__internalCellMeasurerFlag&&(t=t.prop...
  function H (line 88) | function H(e){var t=e.cellCount,n=e.overscanCellsCount,r=e.scrollDirecti...
  function F (line 88) | function F(e,t,n,r,o){this.mid=e,this.left=t,this.right=n,this.leftPoint...
  function V (line 88) | function V(e,t){e.mid=t.mid,e.left=t.left,e.right=t.right,e.leftPoints=t...
  function P (line 88) | function P(e,t){var n=Z(t);e.mid=n.mid,e.left=n.left,e.right=n.right,e.l...
  function Y (line 88) | function Y(e,t){var n=e.intervals([]);n.push(t),P(e,n)}
  function G (line 88) | function G(e,t){var n=e.intervals([]),r=n.indexOf(t);return 0>r?0:(n.spl...
  function W (line 88) | function W(e,t,n){for(var r=0;r<e.length&&e[r][0]<=t;++r){var o=n(e[r]);...
  function X (line 88) | function X(e,t,n){for(var r=e.length-1;r>=0&&e[r][1]>=t;--r){var o=n(e[r...
  function _ (line 88) | function _(e,t){for(var n=0;n<e.length;++n){var r=t(e[n]);if(r)return r}}
  function q (line 88) | function q(e,t){return e-t}
  function J (line 88) | function J(e,t){var n=e[0]-t[0];return n||e[1]-t[1]}
  function K (line 88) | function K(e,t){var n=e[1]-t[1];return n||e[0]-t[0]}
  function Z (line 88) | function Z(e){if(0===e.length)return null;for(var t=[],n=0;n<e.length;++...
  function $ (line 88) | function $(e){this.root=e}
  function ee (line 88) | function ee(){}
  function te (line 88) | function te(e){var t=e.dataKey,n=e.rowData;return"function"==typeof n.ge...
  function ne (line 88) | function ne(e){var t=e.cellData;return null==t?"":String(t)}
  function re (line 88) | function re(e){var t=e.className,r=e.columns,o=e.style;return n.createEl...
  function oe (line 88) | function oe(e){var t=e.sortDirection,r=L("ReactVirtualized__Table__sorta...
  function ie (line 88) | function ie(e){var t=e.dataKey,r=e.label,o=e.sortBy,i=e.sortDirection,a=...
  function ae (line 88) | function ae(e){var t=e.className,r=e.columns,o=e.index,i=e.key,a=e.onRow...
  function se (line 88) | function se(){mt&&(mt=null,document.body&&null!=ft&&(document.body.style...
  function le (line 88) | function le(){se(),gt.forEach(function(e){return e.__resetIsScrolling()})}
  function ce (line 88) | function ce(e){e.currentTarget===window&&null==ft&&document.body&&(ft=do...
  function ue (line 88) | function ue(e,t){gt.some(function(e){return e.props.scrollElement===t})|...
  function de (line 88) | function de(e,t){(gt=gt.filter(function(t){return t!==e})).length||(t.re...
  function pe (line 88) | function pe(e,t){if(e){if(At(e)){var n=window,r=n.innerHeight,o=n.innerW...
  function he (line 88) | function he(e){return At(e)&&document.documentElement?{top:"scrollY"in w...
  function e (line 88) | function e(){var t,n;o(this,e);for(var r=arguments.length,i=new Array(r)...
  function e (line 88) | function e(){var t,n;o(this,e);for(var r=arguments.length,i=new Array(r)...
  function e (line 88) | function e(){var t,n;o(this,e);for(var r=arguments.length,i=new Array(r)...
  function e (line 88) | function e(){var t=this,n=0<arguments.length&&void 0!==arguments[0]?argu...
  function n (line 88) | function n(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t...
  function r (line 88) | function r(e){return n(e)===h}
  function e (line 88) | function e(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t...
  function n (line 88) | function n(t){return e(t)===p}
  function e (line 88) | function e(){var t,n;o(this,e);for(var r=arguments.length,i=new Array(r)...
  function e (line 89) | function e(t){var n=t.height,r=t.width,i=t.x,a=t.y;o(this,e),this.height...
  function e (line 89) | function e(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0...
  function e (line 89) | function e(t,n){var r;return o(this,e),(r=m(this,p(e).call(this,t,n)))._...
  function e (line 89) | function e(t,n){var r;return o(this,e),(r=m(this,p(e).call(this,t,n)))._...
  function e (line 89) | function e(t){var n=t.cellCount,r=t.cellSizeGetter,i=t.estimatedCellSize...
  function e (line 89) | function e(t){var n=t.maxScrollSize,r=void 0===n?Ye():n,i=g(t,["maxScrol...
  function e (line 89) | function e(t){var n;o(this,e),s(f(n=m(this,p(e).call(this,t))),"_onGridR...
  function e (line 90) | function e(t,n){var r;return o(this,e),(r=m(this,p(e).call(this,t,n)))._...
  function e (line 90) | function e(){var t,n;o(this,e);for(var r=arguments.length,i=new Array(r)...
  function e (line 90) | function e(){o(this,e),s(this,"_columnSizeMap",{}),s(this,"_intervalTree...
  function e (line 90) | function e(){var t,n;o(this,e);for(var r=arguments.length,i=new Array(r)...
  function e (line 90) | function e(){var t=this,n=0<arguments.length&&void 0!==arguments[0]?argu...
  function e (line 90) | function e(t,r){var i;o(this,e),s(f(i=m(this,p(e).call(this,t,r))),"stat...
  function e (line 91) | function e(t,n){var r;return o(this,e),(r=m(this,p(e).call(this,t,n))).s...
  function e (line 91) | function e(){return o(this,e),m(this,p(e).apply(this,arguments))}
  function e (line 91) | function e(t){var n;return o(this,e),(n=m(this,p(e).call(this,t))).state...
  function e (line 91) | function e(){var t,n;o(this,e);for(var r=arguments.length,i=new Array(r)...
  function t (line 91) | function t(e){for(var t=0,n=1;n<r.length;n++)r[n]<r[t]&&(t=n);var i=t*(a...
  function n (line 91) | function n(){r=[];for(var e=0;i>e;e++)r[e]=0}
  function r (line 91) | function r(e){return e>0?e:320}
  function o (line 91) | function o(e,t){a.toDataURL(e.url,{width:r(e.width),height:r(e.height),m...
  function r (line 91) | function r(){return[{title:"APP",name:"app",className:"app",selected:!0,...
  function o (line 91) | function o(e,t){g=g||r(),h=g.concat(T),h.forEach(function(e){for(var t,n...
  function i (line 91) | function i(e){if(p={},e){try{f=JSON.parse(v.get("networkColumnsWidth"))}...
  function a (line 91) | function a(e){var t=[],n=[];x.forEach(function(n){var r=n&&n.name,o=r&&p...
  function s (line 91) | function s(){y.columns=h,M.setNetworkColumns(y)}
  function l (line 91) | function l(e,t){if(e!==t){var n=p[e],r=p[t];if(n&&r){var o=h.indexOf(n),...
  function c (line 91) | function c(e){var t=e.target,n=t.nodeName;return"TH"===n||"LABEL"===n?t:...
  function u (line 91) | function u(e){var t=c(e),n=t&&t.getAttribute("data-name");if(n){var r=d(...
  function d (line 91) | function d(e){var t=b.findArray(e.dataTransfer.types,function(e){return ...
  function r (line 92) | function r(e){return e.rawPattern+" @"+u(e).substring(4)+s(e)}
  function o (line 92) | function o(e){return e.rawPattern+" %"+u(e).substring(4)+s(e)}
  function i (line 92) | function i(e){return e?" "+e:""}
  function a (line 92) | function a(e){return-1!==e.indexOf("important")}
  function s (line 92) | function s(e){return e&&e.file?M.SOURCE_SEP+e.file+")":""}
  function l (line 92) | function l(e,t){var n=i(e.filter);return(e=e.rawProps)?(t||(e=e.filter(a...
  function c (line 92) | function c(e){return e.strictHtml?" enable://strictHtml":e.safeHtml?" en...
  function u (line 92) | function u(e){return e._matcher||e.matcher}
  function d (line 92) | function d(e){if(e){var t=u(e);if(e.port){var n=t.indexOf(":")+3,r=t.sub...
  function p (line 92) | function p(e){return"-"===e?"":e}
  function h (line 92) | function h(e){return-1!==S.indexOf(e)||"skip"===e||/^x/.test(e)}
  function r (line 92) | function r(e,t){return e>t?1:-1}
  function r (line 93) | function r(e,t){"function"==typeof e&&e(l(t))}
  function r (line 94) | function r(e){return e.active}
  function r (line 94) | function r(){this.list=[]}
  function o (line 94) | function o(e){for(var t=0,n=e.length;n>t;t++){var r=e[t];if(r.active)ret...
  function i (line 94) | function i(e,t){var n=o(e);e.splice(0,t),n&&-1===e.indexOf(n)&&(e[0]=n)}
  function r (line 94) | function r(e,t){return"string"!=typeof e?"":(t=t||K,e.length>t?e.substri...
  function o (line 94) | function o(e,t,n){return"CONNECT"===e||v.hasRequestBody(e)||W.test(t)?!0...
  function i (line 94) | function i(e){return e=v.getBase64FromHexText(e),v.base64Decode(e)}
  function a (line 94) | function a(e){var t=v.toBase64(e);return v.getHexText(v.getHexFromBase64...
  function s (line 94) | function s(e){for(var t,n=Object.keys(e),r=0,o=n.length;o>r;r++){var i=n...
  function l (line 94) | function l(e){return"upload"===e||"upload"===s(e)}
  function c (line 94) | function c(e){return e=e.join("\n"),e&&encodeURIComponent(e)}
  function u (line 94) | function u(e,t){return e&&(e=(e+"").replace(/;?\s*boundary=.*$/,"")),(e|...
  function d (line 94) | function d(e){return 403==e?"forbidden":e&&(!/^\d+$/.test(e)||e>=400)?"e...
  function p (line 94) | function p(e){e&&"object"===("undefined"==typeof e?"undefined":f(e))&&(e...
  function h (line 94) | function h(e){return e&&e.replace(/\r\n|\r|\n/g,"\r\n")}
  function g (line 94) | function g(e){if(e&&e.endTime){var t=e.endTime-e.startTime;return t>=1e3...
  function r (line 96) | function r(e){return!(!e||null!=e.body||!e.dataHash&&!e.base64Hash)}
  function o (line 96) | function o(e,t){if(i===e&&a===t)return s;var n=[e.method+" "+e.url+" HTT...
  function r (line 96) | function r(e,t){if(e.view)return e.view;try{var n=JSON.parse(e.text),r=n...
  function o (line 96) | function o(e){var t=["Level: "+e.level.toUpperCase()];return e.logId&&t....
  function r (line 97) | function r(){return L&&"auto"===U||"dark"===U}
  function o (line 97) | function o(e){U=e,j()}
  function i (line 97) | function i(e){var t;try{t=window.matchMedia("(prefers-color-scheme: dark...
  function a (line 97) | function a(e){try{var t=e.contentDocument.documentElement.style;t.colorS...
  function s (line 97) | function s(e){if("fake"===e.getAttribute("data-type"))return a(e);try{va...
  function l (line 97) | function l(e){e=+e,2===D?(1>e||e>E)&&(e=1):1===D?2!==e&&e!==E&&(e=1):e!=...
  function c (line 97) | function c(e){var t=[];return e?(t.push('<option value="1">Verbatim</opt...
  function u (line 97) | function u(){if(!p){var e=['<h5><strong>Uptime:</strong> <span id="whist...
  function d (line 97) | function d(e){return e.map(function(e){return"  "+e})}
  function r (line 98) | function r(e,t,n,r){return e?Object.keys(e).sort(T.getPluginComparator(e...
  function o (line 98) | function o(e){if(!e)return"";e=e.split(O);for(var t=0,n=e.length;n>t;t++...
  function i (line 98) | function i(e){m||(m=setTimeout(function(){m=null},2e3),b.trigger("disabl...
  function a (line 98) | function a(e,t){var n=e?" --account="+e:"";return n+(t?" --dir="+t:"")}
  function s (line 98) | function s(e){var t=x.getServerInfo().cmdName,n="";return t&&U.test(t)?(...
  function l (line 98) | function l(e){return a(e.account,e.dir)}
  function c (line 98) | function c(e){return e.updateUrl||e.moduleName}
  function u (line 98) | function u(e){return e.rules||e._rules||e.resRules}
  function d (line 98) | function d(e){return(e.pluginHomepage||e.openExternal)&&!e.openInPlugins...
  function p (line 98) | function p(e){return e.pluginHomepage||"plugin."+T.getSimplePluginName(e...
  function h (line 98) | function h(e){return/^https?:\/\/[^/?]/.test(e)&&e.length<=1024?e:""}
  function g (line 98) | function g(e,t){if(T.isString(e))e=e.split(/[\s,;|]+/);else if(!Array.is...
  function f (line 98) | function f(e){if(!e)return"";var t=[];return t.push("Name: "+e.moduleNam...
  function e (line 99) | function e(){clearTimeout(n),n=setTimeout(t,60)}
  function t (line 99) | function t(){if(!r.props.hide){var e=i.offsetHeight;e&&(o.style.width=i....
  function r (line 99) | function r(e){if(e&&"string"==typeof e){e=e.trim().split(d);for(var t=0,...
  function r (line 99) | function r(e){e=e||c.get("previewRulesName");var t=s.getRulesModal();if(...
  function r (line 100) | function r(e){var t=e&&e.trim();return t&&"{"===t[0]&&"}"===t[t.length-1...
  function o (line 100) | function o(e){return e?null:D}
  function i (line 100) | function i(e){return e=e&&e.trim()||"","localhost"===e||Q.test(e)||z.tes...
  function a (line 100) | function a(e){return e?e.trim():""}
  function s (line 100) | function s(e,t,n){return"\n"+t+" "+e+"\n"+n+"\n"+t}
  function l (line 100) | function l(e,t){if(e=a(e),!e||!t)return"";var n="```";if(-1===t.indexOf(...
  function c (line 100) | function c(e,t){var n=e.req,r=e.res||"";switch(t){case"blank":return"";c...
  function u (line 100) | function u(e){return"("===e[0]&&")"===e[e.length-1]}
  function r (line 100) | function r(e,t){"function"==typeof e&&e(a(t))}
  function r (line 100) | function r(e){return"network"===e?".txt,.json,.saz,.har":"console"===e||...
  function o (line 100) | function o(e){if("{"===e[0]||"["===e[0])try{return JSON.parse(e)}catch(t...
  function n (line 101) | function n(e){for(var t=[],n="",r=function(e){if(null!=e[5])throw new Er...
  function r (line 101) | function r(e){return n(e).reduce(function(e,t){return t?(t.indexOf("-X")...
  function r (line 101) | function r(e){return"crt"===e||"pem"===e?e:"cer"}
  function r (line 101) | function r(e,t){return t=t||e.filename,t+"."+(e.type||"crt")}
  function o (line 101) | function o(e,t){var n=new FileReader;n.readAsText(e),n.onload=function()...

FILE: biz/webui/htdocs/src/js/bridge.js
  function compatAjax (line 14) | function compatAjax(options) {
  function getPlugin (line 21) | function getPlugin(win) {
  function getBridge (line 39) | function getBridge(win, api) {

FILE: biz/webui/htdocs/src/js/certs-info-dialog.js
  function getCertName (line 17) | function getCertName(cert, filename) {
  function readFile (line 22) | function readFile(file, callback) {

FILE: biz/webui/htdocs/src/js/cgi.js
  function createCgi (line 6) | function createCgi(url, settings) {
  function create (line 65) | function create(obj, settings) {

FILE: biz/webui/htdocs/src/js/columns.js
  function getDefaultColumns (line 13) | function getDefaultColumns() {
  function updateColumns (line 182) | function updateColumns(reseted, init) {
  function reset (line 215) | function reset(init) {
  function sortColumns (line 233) | function sortColumns(init) {
  function save (line 261) | function save() {
  function moveTo (line 270) | function moveTo(name, targetName) {
  function getTarget (line 315) | function getTarget(e) {
  function getDragInfo (line 330) | function getDragInfo(e) {
  function getNameFromTypes (line 345) | function getNameFromTypes(e) {

FILE: biz/webui/htdocs/src/js/components/json/stringify.js
  function f (line 159) | function f(n) {
  function this_value (line 164) | function this_value() {
  function quote (line 196) | function quote(string) {
  function str (line 215) | function str(key, holder) {

FILE: biz/webui/htdocs/src/js/components/react-json-tree/ItemRange.js
  function _interopRequireDefault (line 31) | function _interopRequireDefault(obj) {
  function ItemRange (line 38) | function ItemRange(props) {

FILE: biz/webui/htdocs/src/js/components/react-json-tree/JSONArrayNode.js
  function _interopRequireDefault (line 23) | function _interopRequireDefault(obj) {
  function createItemString (line 29) | function createItemString(data) {

FILE: biz/webui/htdocs/src/js/components/react-json-tree/JSONArrow.js
  function _interopRequireDefault (line 13) | function _interopRequireDefault(obj) {

FILE: biz/webui/htdocs/src/js/components/react-json-tree/JSONIterableNode.js
  function _interopRequireDefault (line 33) | function _interopRequireDefault(obj) {
  function createItemString (line 39) | function createItemString(data, limit) {
  function JSONIterableNode (line 86) | function JSONIterableNode(_ref2) {

FILE: biz/webui/htdocs/src/js/components/react-json-tree/JSONNestedNode.js
  function _interopRequireDefault (line 51) | function _interopRequireDefault(obj) {
  function renderChildNodes (line 59) | function renderChildNodes(props, from, to) {
  function getStateFromProps (line 125) | function getStateFromProps(props) {
  function JSONNestedNode (line 139) | function JSONNestedNode(props) {

FILE: biz/webui/htdocs/src/js/components/react-json-tree/JSONNode.js
  function _interopRequireDefault (line 43) | function _interopRequireDefault(obj) {

FILE: biz/webui/htdocs/src/js/components/react-json-tree/JSONObjectNode.js
  function _interopRequireDefault (line 27) | function _interopRequireDefault(obj) {
  function createItemString (line 33) | function createItemString(data) {

FILE: biz/webui/htdocs/src/js/components/react-json-tree/JSONValueNode.js
  function _interopRequireDefault (line 17) | function _interopRequireDefault(obj) {

FILE: biz/webui/htdocs/src/js/components/react-json-tree/createStylingFromTheme.js
  function _interopRequireDefault (line 15) | function _interopRequireDefault(obj) {

FILE: biz/webui/htdocs/src/js/components/react-json-tree/getCollectionEntries.js
  function _interopRequireDefault (line 19) | function _interopRequireDefault(obj) {
  function getLength (line 23) | function getLength(type, collection) {
  function isIterableMap (line 33) | function isIterableMap(collection) {
  function getEntries (line 37) | function getEntries(type, collection, sortObjectKeys) {
  function getRanges (line 133) | function getRanges(from, to, limit) {
  function getCollectionEntries (line 145) | function getCollectionEntries(type, collection, sortObjectKeys, limit) {

FILE: biz/webui/htdocs/src/js/components/react-json-tree/index.js
  function _interopRequireDefault (line 59) | function _interopRequireDefault(obj) {
  function checkLegacyTheming (line 97) | function checkLegacyTheming(theme, props) {
  function getStateFromProps (line 155) | function getStateFromProps(props) {
  function JSONTree (line 182) | function JSONTree(props) {

FILE: biz/webui/htdocs/src/js/components/react-json-tree/objType.js
  function _interopRequireDefault (line 11) | function _interopRequireDefault(obj) {
  function objType (line 15) | function objType(obj) {

FILE: biz/webui/htdocs/src/js/composer.js
  function getString (line 109) | function getString(str, len) {
  function hasReqBody (line 117) | function hasReqBody(method, url, headers) {
  function hexToStr (line 124) | function hexToStr(str) {
  function strToHex (line 129) | function strToHex(str) {
  function getType (line 134) | function getType(headers) {
  function isUpload (line 154) | function isUpload(headers) {
  function escapeRules (line 158) | function escapeRules(rules) {
  function getUploadType (line 163) | function getUploadType(type, boundary) {
  function getStatus (line 170) | function getStatus(statusCode) {
  function parseValue (line 180) | function parseValue(value) {
  function replaceCRLF (line 187) | function replaceCRLF(body) {
  function getComposerTime (line 191) | function getComposerTime(composerTime) {

FILE: biz/webui/htdocs/src/js/console.js
  function parseLog (line 25) | function parseLog(log, expandRoot) {
  function getLogInfo (line 61) | function getLogInfo(log) {

FILE: biz/webui/htdocs/src/js/data-center.js
  function updateRulesInfo (line 137) | function updateRulesInfo(data) {
  function compareFilter (line 146) | function compareFilter(filter) {
  function handleHashFilterChanged (line 161) | function handleHashFilterChanged(e) {
  function setFilterText (line 216) | function setFilterText(settings) {
  function getFilterText (line 230) | function getFilterText() {
  function setNetworkColumns (line 250) | function setNetworkColumns(settings) {
  function getNetworkColumns (line 262) | function getNetworkColumns() {
  function getFilterCache (line 280) | function getFilterCache(text) {
  function resolveFilterText (line 297) | function resolveFilterText(text) {
  function checkFilterField (line 340) | function checkFilterField(str, filter, needDecode) {
  function checkFilter (line 361) | function checkFilter(item, list) {
  function toLowerCase (line 438) | function toLowerCase(str) {
  function createCompose (line 597) | function createCompose(cancel) {
  function handleCompose (line 611) | function handleCompose(data, cb, options, handler) {
  function getSavedListSafe (line 692) | function getSavedListSafe (cb) {
  function updateCertStatus (line 732) | function updateCertStatus(data) {
  function filterComposeData (line 763) | function filterComposeData(key) {
  function getComposeData (line 767) | function getComposeData(keys, cb) {
  function loadComposeData (line 773) | function loadComposeData(keys) {
  function checkDataChanged (line 881) | function checkDataChanged(data, mclientName, mtimeName) {
  function emitRulesChanged (line 899) | function emitRulesChanged(data) {
  function emitValuesChanged (line 905) | function emitValuesChanged(data) {
  function checkTabList (line 911) | function checkTabList(list1, list2, len) {
  function hasPluginColsChange (line 921) | function hasPluginColsChange(curCols, oldClos) {
  function emitCustomTabsChange (line 936) | function emitCustomTabsChange(curList, oldList, name) {
  function getBase64Len (line 962) | function getBase64Len(base64) {
  function updateItem (line 976) | function updateItem(item, newItem) {
  function getStatus (line 1001) | function getStatus(item) {
  function getComposerItem (line 1013) | function getComposerItem() {
  function startLoadData (line 1019) | function startLoadData() {
  function getRawHeaders (line 1399) | function getRawHeaders(headers, rawHeaderNames) {
  function getReqId (line 1416) | function getReqId() {
  function isFrames (line 1457) | function isFrames(item) {
  function getStyleValue (line 1476) | function getStyleValue(style) {
  function getCustomValue (line 1491) | function getCustomValue(style, isFirst) {
  function setStyle (line 1507) | function setStyle(item) {
  function getAppName (line 1556) | function getAppName(ua) {
  function setAppName (line 1638) | function setAppName(item) {
  function hasRules (line 1662) | function hasRules(rules) {
  function setReqData (line 1677) | function setReqData(item) {
  function checkUrl (line 1771) | function checkUrl(data) {
  function overflowCount (line 1847) | function overflowCount() {
  function getStartTime (line 1855) | function getStartTime() {
  function updateServerInfo (line 1865) | function updateServerInfo(data) {
  function isDisabledPlugin (line 2014) | function isDisabledPlugin(name) {
  function getMenus (line 2042) | function getMenus(menuName) {
  function toString (line 2163) | function toString(options) {
  function triggerWhistleIdChanged (line 2167) | function triggerWhistleIdChanged(server, byServer) {
  function updateWhistleId (line 2193) | function updateWhistleId(server) {

FILE: biz/webui/htdocs/src/js/decode.js
  function base64toBytes (line 12) | function base64toBytes(base64) {

FILE: biz/webui/htdocs/src/js/editor-dialog.js
  function getTempFile (line 24) | function getTempFile(tempFile, cb) {

FILE: biz/webui/htdocs/src/js/editor.js
  function hasSelector (line 69) | function hasSelector(selector) {
  function resize (line 328) | function resize() {
  function resetThrottle (line 339) | function resetThrottle() {

FILE: biz/webui/htdocs/src/js/frame-data.js
  function findActive (line 12) | function findActive(btn) {

FILE: biz/webui/htdocs/src/js/frame-modal.js
  function FramesModal (line 4) | function FramesModal() {
  function getActive (line 106) | function getActive(list) {
  function updateList (line 115) | function updateList(list, len) {

FILE: biz/webui/htdocs/src/js/history-data.js
  function noData (line 33) | function noData(item) {
  function getRaw (line 37) | function getRaw(item, disabled) {

FILE: biz/webui/htdocs/src/js/https-settings.js
  function getCAType (line 14) | function getCAType(type) {

FILE: biz/webui/htdocs/src/js/iframe-dialog.js
  function onWhistlePluginOptionModalReady (line 9) | function onWhistlePluginOptionModalReady(init, win) {

FILE: biz/webui/htdocs/src/js/iframes.js
  function destroy (line 11) | function destroy(item) {
  function getItem (line 39) | function getItem(win) {
  function onPluginContextMenuReady (line 54) | function onPluginContextMenuReady(win) {
  function removeOldest (line 88) | function removeOldest() {

FILE: biz/webui/htdocs/src/js/import-dialog.js
  function getAccept (line 16) | function getAccept(name) {
  function parseJson (line 29) | function parseJson(text) {

FILE: biz/webui/htdocs/src/js/index.js
  function getHideStyle (line 75) | function getHideStyle(hide) {
  function getString (line 79) | function getString(url) {
  function isTextFile (line 83) | function isTextFile(url) {
  function getJsonForm (line 197) | function getJsonForm(data, name) {
  function readFileJson (line 204) | function readFileJson(file, cb) {
  function handleImportData (line 226) | function handleImportData(file, cb, type) {
  function getPageName (line 235) | function getPageName(options) {
  function parseJSON (line 265) | function parseJSON(text) {
  function compareSelectedNames (line 274) | function compareSelectedNames(src, target) {
  function getKey (line 293) | function getKey(url) {
  function getValue (line 302) | function getValue(url) {
  function appendList (line 311) | function appendList(list, _list) {
  function updateData (line 325) | function updateData(list, data, modal) {
  function getCAType (line 357) | function getCAType(type) {
  function getKey (line 1555) | function getKey(url) {
  function update (line 2222) | function update(modal, _atBottom) {
  function scrollToBottom (line 2241) | function scrollToBottom(force) {
  function atBottom (line 2261) | function atBottom(force) {

FILE: biz/webui/htdocs/src/js/is-utf8.js
  function isUtf8 (line 3) | function isUtf8(buf, i) {

FILE: biz/webui/htdocs/src/js/json-viewer.js
  function compare (line 28) | function compare(a, b) {

FILE: biz/webui/htdocs/src/js/list-modal.js
  function ListModal (line 4) | function ListModal(list, data) {
  function push (line 94) | function push(list, name) {
  function add (line 105) | function add(name, value, isPre) {
  function setNot (line 435) | function setNot(flag, not) {
  function isVisibleItem (line 517) | function isVisibleItem(item) {

FILE: biz/webui/htdocs/src/js/list.js
  function getTarget (line 79) | function getTarget(e) {
  function getName (line 94) | function getName(name) {
  function getDragInfo (line 101) | function getDragInfo(e, list) {
  function getNameFromTypes (line 119) | function getNameFromTypes(e) {
  function getSuffix (line 135) | function getSuffix(name) {
  function trigger (line 176) | function trigger(item) {

FILE: biz/webui/htdocs/src/js/message.js
  function showMessage (line 10) | function showMessage(msg, level) {

FILE: biz/webui/htdocs/src/js/mock-dialog.js
  function getDefaultValue (line 44) | function getDefaultValue(value) {
  function getStyle (line 52) | function getStyle(show) {
  function getDefaultHost (line 56) | function getDefaultHost(value) {
  function trim (line 64) | function trim(str) {
  function wrapValue (line 68) | function wrapValue(name, sep, str) {
  function getInlineValue (line 72) | function getInlineValue(name, str) {
  function getValue (line 92) | function getValue(item, key) {
  function isValue (line 124) | function isValue(str) {

FILE: biz/webui/htdocs/src/js/modal.js
  function getFlag (line 15) | function getFlag() {
  function removeWinField (line 22) | function removeWinField(name) {
  function createModal (line 30) | function createModal(options, callback, gVarName) {
  function addEvents (line 71) | function addEvents(html, gVarName) {
  function updateCtn (line 89) | function updateCtn(con, html, name) {
  function initModal (line 98) | function initModal(dialog, options, gVarName) {

FILE: biz/webui/htdocs/src/js/network-modal.js
  function NetworkModal (line 22) | function NetworkModal(list) {
  function parseKeyword (line 56) | function parseKeyword(keyword) {
  function parseKeywordList (line 85) | function parseKeywordList(keyword) {
  function checkKeywork (line 122) | function checkKeywork(str, opts) {
  function checkUrl (line 134) | function checkUrl(item, opts) {
  function checkData (line 142) | function checkData(item, opts) {
  function setNot (line 168) | function setNot(flag, not) {
  function hasError (line 172) | function hasError(item) {
  function checkItem (line 178) | function checkItem(item, opts) {
  function toStr (line 274) | function toStr(val) {
  function checkFilterType (line 281) | function checkFilterType(item, filterType) {
  function compare (line 427) | function compare(prev, next, order, name) {
  function _compare (line 442) | function _compare(prev, next, name) {
  function inObject (line 466) | function inObject(obj, opts) {
  function getNodeIdMap (line 519) | function getNodeIdMap(node, map) {
  function updateList (line 732) | function updateList(list, len, hasKeyword) {
  function getActive (line 793) | function getActive(list) {
  function getPrevSelected (line 829) | function getPrevSelected(start, list) {
  function getNextSelected (line 839) | function getNextSelected(start, list) {
  function parsePaths (line 892) | function parsePaths(url) {
  function checkHide (line 914) | function checkHide(item) {
  function handleTree (line 933) | function handleTree(root, list) {
  function updateOrder (line 1056) | function updateOrder(list, force) {

FILE: biz/webui/htdocs/src/js/online.js
  function isDarkMode (line 46) | function isDarkMode() {
  function setAppearanceMode (line 50) | function setAppearanceMode(mode) {
  function onDarkModeChange (line 55) | function onDarkModeChange(cb) {
  function updateFakeIframe (line 79) | function updateFakeIframe(iframe) {
  function updateIframeTheme (line 89) | function updateIframeTheme(iframe) {
  function selectDnsOption (line 113) | function selectDnsOption(order) {
  function getDnsOrder (line 133) | function getDnsOrder(verbatim) {
  function createDialog (line 150) | function createDialog() {
  function addIndent (line 208) | function addIndent(list) {

FILE: biz/webui/htdocs/src/js/overview.js
  function getAtRule (line 94) | function getAtRule(rule) {
  function getVarRule (line 98) | function getVarRule(rule) {
  function getStr (line 102) | function getStr(str) {
  function filterImportant (line 106) | function filterImportant(item) {
  function getPluginName (line 110) | function getPluginName(rule) {
  function getRawProps (line 114) | function getRawProps(rule, all) {
  function getInjectProps (line 126) | function getInjectProps(rule) {
  function getMatcher (line 134) | function getMatcher(rule) {
  function getRuleStr (line 138) | function getRuleStr(rule) {
  function getTime (line 154) | function getTime(time) {
  function ignoreProtocol (line 158) | function ignoreProtocol(name) {

FILE: biz/webui/htdocs/src/js/parse-curl.js
  function split (line 23) | function split(str) {
  function parseArgs (line 65) | function parseArgs(s) {

FILE: biz/webui/htdocs/src/js/parse-rules.js
  function isPattern (line 14) | function isPattern(item) {
  function getPatternIndex (line 23) | function getPatternIndex(list) {
  function getFilters (line 41) | function getFilters(list) {

FILE: biz/webui/htdocs/src/js/plugins-mgr.js
  function getRegistry (line 12) | function getRegistry(cmd) {

FILE: biz/webui/htdocs/src/js/plugins.js
  function getPluginList (line 46) | function getPluginList(plugins, installUrls, disabledPlugins, disabledAl...
  function parseRegistry (line 61) | function parseRegistry(cmd) {
  function enableAllPlugins (line 75) | function enableAllPlugins(e) {
  function getArgvs (line 85) | function getArgvs(account, dir) {
  function getCmd (line 90) | function getCmd(addArgv) {
  function getParams (line 107) | function getParams(plugin) {
  function getUpdateUrl (line 111) | function getUpdateUrl(plugin) {
  function hasRules (line 115) | function hasRules(plugin) {
  function isOpenExternal (line 119) | function isOpenExternal(plugin) {
  function getHomePage (line 123) | function getHomePage(plugin) {
  function getRegistry (line 127) | function getRegistry(url) {
  function parsePluginName (line 131) | function parsePluginName(list, registry) {
  function getPluginInfo (line 821) | function getPluginInfo(plugin) {
  function resizeHandler (line 841) | function resizeHandler() {
  function _resizeHandler (line 846) | function _resizeHandler() {

FILE: biz/webui/htdocs/src/js/properties.js
  function getSrcInfo (line 16) | function getSrcInfo(val, sep) {

FILE: biz/webui/htdocs/src/js/protocols.js
  function getPlugin (line 213) | function getPlugin(rule) {

FILE: biz/webui/htdocs/src/js/qrcode.js
  function getSize (line 4) | function getSize(size) {
  function getDataURL (line 8) | function getDataURL(options, cb) {

FILE: biz/webui/htdocs/src/js/recycle-bin.js
  function decode (line 15) | function decode(name) {

FILE: biz/webui/htdocs/src/js/req-data.js
  function getColStyle (line 153) | function getColStyle(col, style) {
  function getRuleStyle (line 159) | function getRuleStyle(data) {
  function getClassName (line 171) | function getClassName(data) {
  function isVisible (line 182) | function isVisible(item) {
  function isVisibleInTree (line 186) | function isVisibleInTree(item) {
  function getStatusClass (line 191) | function getStatusClass(data) {
  function getType (line 231) | function getType(className) {
  function getIcon (line 256) | function getIcon(data, className) {
  function removeHighlight (line 274) | function removeHighlight(elem) {

FILE: biz/webui/htdocs/src/js/rules-dialog.js
  function getName (line 16) | function getName(name) {

FILE: biz/webui/htdocs/src/js/rules-hint.js
  function isExactMatch (line 130) | function isExactMatch(curWord, list) {
  function getInlineKeys (line 138) | function getInlineKeys() {
  function getHintCgi (line 167) | function getHintCgi(plugin, pluginVars) {
  function getHints (line 184) | function getHints(keyword) {
  function getFilterHint (line 237) | function getFilterHint(filter) {
  function getFilterHints (line 246) | function getFilterHints(keyword, filter1, filter2) {
  function getSpecHints (line 264) | function getSpecHints(keyword, protocol, hints) {
  function getAtValueList (line 281) | function getAtValueList(keyword) {
  function getSpecHint (line 321) | function getSpecHint(name, specProto) {
  function getPluginVarHints (line 328) | function getPluginVarHints(keyword, specProto) {
  function getAtHelpUrl (line 361) | function getAtHelpUrl(name, options) {
  function getRuleHelp (line 374) | function getRuleHelp(plugin, helpUrl) {
  function getHintText (line 383) | function getHintText(protoName, text, isVar, isKey) {
  function handleRemoteHints (line 390) | function handleRemoteHints(data, editor, plugin, protoName, value, cgi, ...
  function isFilterProtocol (line 455) | function isFilterProtocol(name) {
  function getSpecProto (line 459) | function getSpecProto(keyword) {
  function getSpecHintOptions (line 489) | function getSpecHintOptions(list) {
  function completeAfter (line 886) | function completeAfter(cm, pred) {
  function getFocusRuleName (line 903) | function getFocusRuleName(editor) {

FILE: biz/webui/htdocs/src/js/rules-mode.js
  function notPort (line 20) | function notPort(port) {
  function isIP (line 25) | function isIP(str) {
  function isHost (line 48) | function isHost(str) {
  function isHead (line 51) | function isHead(str) {
  function isWeinre (line 55) | function isWeinre(str) {
  function isReq (line 59) | function isReq(str) {
  function isRes (line 65) | function isRes(str) {
  function isUrl (line 71) | function isUrl(str) {
  function isRule (line 75) | function isRule(str) {
  function notExistRule (line 79) | function notExistRule(str) {
  function notExistPlugin (line 84) | function notExistPlugin(str) {
  function isRegExp (line 89) | function isRegExp(str) {
  fun
Condensed preview — 837 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (5,418K chars).
[
  {
    "path": ".babelrc",
    "chars": 210,
    "preview": "{\n  \"presets\": [\n    \"env\",\n    \"react\"\n  ],\n  \"plugins\": [\n    \"transform-class-properties\",\n    \"transform-object-rest"
  },
  {
    "path": ".editorconfig",
    "chars": 292,
    "preview": "# http://editorconfig.org\nroot = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\nindent_size = 2\nindent_style = space\ninsert_"
  },
  {
    "path": ".eslintignore",
    "chars": 158,
    "preview": "node_modules\n/biz/webui/htdocs/js\n/biz/webui/htdocs/src/js/components\n/test/assets/values\n/test/plugins/whistle.test/ass"
  },
  {
    "path": ".eslintrc",
    "chars": 876,
    "preview": "{\n  \"env\": {\n    \"browser\": true,\n    \"node\": true,\n    \"es6\": true\n  },\n  \"extends\": [\n    \"eslint:recommended\",\n    \"p"
  },
  {
    "path": ".gitattributes",
    "chars": 41,
    "preview": "biz/webui/htdocs/js/index.js diff=nodiff\n"
  },
  {
    "path": ".gitignore",
    "chars": 898,
    "preview": "# Logs\nlogs\n*.log\n.DS_Store\ntmp\n\n# Runtime data\npids\n*.pid\n*.seed\n\n# Directory for instrumented libs generated by jscove"
  },
  {
    "path": ".npmignore",
    "chars": 989,
    "preview": "# Logs\nlogs\n*.log\n.DS_Store\ntmp\n\n# Runtime data\npids\n*.pid\n*.seed\n\n# Directory for instrumented libs generated by jscove"
  },
  {
    "path": ".travis.yml",
    "chars": 203,
    "preview": "language: node_js\nnode_js:\n  - \"10\"\n  - \"11\"\n  - \"12\"\n  - \"13\"\n  - \"14\"\n  - \"15\"\n  - \"16\"\n  - \"17\"\n  - \"18\"\n\ninstall:\n  "
  },
  {
    "path": "CHANGELOG-en_US.md",
    "chars": 49109,
    "preview": "[中文](./CHANGELOG.md) · English\n\n## v2.10.1\n1. fix: https://github.com/avwo/whistle/issues/1296\n2. fix: https://github.co"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 27367,
    "preview": "中文 · [English](./CHANGELOG-en_US.md)\n\n## v2.10.1\n1. fix: https://github.com/avwo/whistle/issues/1296\n2. fix: https://git"
  },
  {
    "path": "LICENSE",
    "chars": 1072,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2015 avwo\n\nPermission is hereby granted, free of charge, to any person obtaining a "
  },
  {
    "path": "README-en_US.md",
    "chars": 3392,
    "preview": "<p align=\"center\">\n  <a href=\"https://avwo.github.io/whistle/\">\n    <img alt=\"whistle logo\" src=\"https://user-images.git"
  },
  {
    "path": "README.md",
    "chars": 2365,
    "preview": "<p align=\"center\">\n  <a href=\"https://avwo.github.io/whistle/\">\n    <img alt=\"whistle logo\" src=\"https://user-images.git"
  },
  {
    "path": "assets/fiddler/meta.xml",
    "chars": 1002,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Session SID=\"${SID}\">\n  <SessionTimers ClientConnected=\"${ClientConnected}\"\n   C"
  },
  {
    "path": "assets/js/log.js",
    "chars": 11482,
    "preview": "\n;(function() {\n  if (typeof window === 'undefined' || typeof Image === 'undefined') {\n    return;\n  }\n\n  if (window._wh"
  },
  {
    "path": "assets/js/weinre.js",
    "chars": 838,
    "preview": "\n;(function() {\n  if (typeof window === 'undefined' || window.WeinreServerURL) {\n    return;\n  }\n  var prefixPath = wind"
  },
  {
    "path": "assets/js/worker.js",
    "chars": 8108,
    "preview": "\nvar exports = {};\nvar module = { exports: exports };\n\n;(function() {\n  var self = null;\n  try {\n    (function() {\n     "
  },
  {
    "path": "assets/menu.html",
    "chars": 8466,
    "preview": "<style>html {background: #fff;}</style>\n<script>\n  ;(function() {\n    var config = window.whistleMenuConfig;\n    var lis"
  },
  {
    "path": "assets/modal.html",
    "chars": 3553,
    "preview": "<!DOCTYPE html>\n<style>html {background: #fff;}</style>\n<script>\n  ;(function() {\n    var toast = {};\n    var whistleBri"
  },
  {
    "path": "assets/tab.html",
    "chars": 11661,
    "preview": "<style>html {background: #fff;}</style>\n<script>\n  ;(function() {\n    var config = window.whistleInspectorConfig;\n    va"
  },
  {
    "path": "bin/ca/cli.js",
    "chars": 3198,
    "preview": "var net = require('net');\nvar fs = require('fs');\nvar path = require('path');\nvar installRootCA = require('./index');\nva"
  },
  {
    "path": "bin/ca/index.d.ts",
    "chars": 50,
    "preview": "export default function (certFile: String): void;\n"
  },
  {
    "path": "bin/ca/index.js",
    "chars": 2213,
    "preview": "var cp = require('child_process');\nvar fs = require('fs');\nvar common = require('../../lib/util/common');\n\nvar spawnSync"
  },
  {
    "path": "bin/import.js",
    "chars": 618,
    "preview": "var fs = require('fs');\n\nfunction importModle(filepath, callback) {\n  return import(filepath).then(callback);\n}\n\nmodule."
  },
  {
    "path": "bin/plugin.d.ts",
    "chars": 208,
    "preview": "\nexport function getWhistlePath(): string;\n\nexport function install(cmd: string, argv: string[]): void;\n\nexport function"
  },
  {
    "path": "bin/plugin.js",
    "chars": 9492,
    "preview": "var cp = require('child_process');\nvar fs = require('fs');\nvar path = require('path');\nvar fse = require('fs-extra2');\nv"
  },
  {
    "path": "bin/proxy.js",
    "chars": 2282,
    "preview": "var net = require('net');\nvar proxy = require('set-global-proxy');\nvar util = require('./util');\n\nvar OFF_RE = /^(?:o|0|"
  },
  {
    "path": "bin/status.js",
    "chars": 1888,
    "preview": "var util = require('./util');\nvar pkg = require('../package.json');\nvar colors = require('colors/safe');\nvar isRunning ="
  },
  {
    "path": "bin/use.js",
    "chars": 5768,
    "preview": "var path = require('path');\nvar http = require('http');\nvar url = require('url');\nvar util = require('./util');\nvar impo"
  },
  {
    "path": "bin/util.js",
    "chars": 5794,
    "preview": "var cp = require('child_process');\nvar program = require('starting');\nvar util = require('util');\nvar os = require('os')"
  },
  {
    "path": "bin/whistle.js",
    "chars": 10188,
    "preview": "#! /usr/bin/env node\n/*eslint no-console: \"off\"*/\nvar program = require('starting');\nvar path = require('path');\nvar htt"
  },
  {
    "path": "biz/index.js",
    "chars": 5948,
    "preview": "var net = require('net');\nvar rules = require('../lib/rules');\nvar util = require('../lib/util');\nvar handleUIReq = requ"
  },
  {
    "path": "biz/init.js",
    "chars": 562,
    "preview": "var http = require('http');\nvar ui = require('./webui/lib');\nvar util = require('../lib/util');\n\nmodule.exports = functi"
  },
  {
    "path": "biz/webui/cgi-bin/abort.js",
    "chars": 327,
    "preview": "var proxy = require('../lib/proxy');\nvar socketMgr = proxy.socketMgr;\n\nfunction abort(reqId) {\n  proxy.abortRequest(reqI"
  },
  {
    "path": "biz/webui/cgi-bin/add-rules-values.js",
    "chars": 648,
    "preview": "var rules = require('../../../lib/rules/util').rules;\nvar values = require('../../../lib/rules/util').values;\n\nmodule.ex"
  },
  {
    "path": "biz/webui/cgi-bin/certs/active.js",
    "chars": 156,
    "preview": "var ca = require('../../../../lib/https/ca');\n\nmodule.exports = function(req, res) {\n  ca.setActiveCert(req.body);\n  res"
  },
  {
    "path": "biz/webui/cgi-bin/certs/all.js",
    "chars": 173,
    "preview": "var ca = require('../../../../lib/https/ca');\n\nmodule.exports = function(req, res) {\n  res.json({\n    certs: ca.getCusto"
  },
  {
    "path": "biz/webui/cgi-bin/certs/remove.js",
    "chars": 240,
    "preview": "var ca = require('../../../../lib/https/ca');\n\nmodule.exports = function(req, res) {\n  ca.removeCert(req.body);\n  var is"
  },
  {
    "path": "biz/webui/cgi-bin/certs/upload.js",
    "chars": 241,
    "preview": "var ca = require('../../../../lib/https/ca');\n\nmodule.exports = function(req, res) {\n  ca.uploadCerts(req.body);\n  var i"
  },
  {
    "path": "biz/webui/cgi-bin/check-update.js",
    "chars": 884,
    "preview": "var properties = require('../../../lib/rules/util').properties;\nvar config = require('../../../lib/config');\nvar common "
  },
  {
    "path": "biz/webui/cgi-bin/cookies.js",
    "chars": 218,
    "preview": "var sendGzip = require('./util').sendGzip;\nvar proxy = require('../lib/proxy');\n\nmodule.exports = function(req, res) {\n "
  },
  {
    "path": "biz/webui/cgi-bin/create-cert.js",
    "chars": 1184,
    "preview": "var Zip = require('adm-zip');\nvar qs = require('querystring');\nvar ca = require('../../../lib/https/ca');\nvar sendError "
  },
  {
    "path": "biz/webui/cgi-bin/custom-frames.js",
    "chars": 329,
    "preview": "var proxy = require('../lib/proxy');\nvar socketMgr = proxy.socketMgr;\n\nmodule.exports = function(req, res) {\n  var resul"
  },
  {
    "path": "biz/webui/cgi-bin/custom-handler.js",
    "chars": 188,
    "preview": "var config = require('../../../lib/config');\n\nmodule.exports = function(req, res) {\n  if (!config.customHandler) {\n    r"
  },
  {
    "path": "biz/webui/cgi-bin/do-not-show-again.js",
    "chars": 233,
    "preview": "var properties = require('../../../lib/rules/util').properties;\n\nmodule.exports = function(req, res) {\n  properties.set("
  },
  {
    "path": "biz/webui/cgi-bin/download.js",
    "chars": 1073,
    "preview": "var util = require('./util');\n\nmodule.exports = function(req, res) {\n  var body = req.body;\n  var filename = body.filena"
  },
  {
    "path": "biz/webui/cgi-bin/enable-http2.js",
    "chars": 199,
    "preview": "var properties = require('../../../lib/rules/util').properties;\n\nmodule.exports = function(req, res) {\n  properties.setE"
  },
  {
    "path": "biz/webui/cgi-bin/get-cert.js",
    "chars": 575,
    "preview": "var ca = require('../../../lib/https/ca');\n\nvar URL_RE = /^(?:(?:[\\w.-]+:)?\\/\\/)?([\\w.-]+)/i;\n\nfunction parseDomain(doma"
  },
  {
    "path": "biz/webui/cgi-bin/get-custom-certs-files.js",
    "chars": 157,
    "preview": "var getCustomCertsFiles = require('../../../lib/https/ca').getCustomCertsFiles;\n\nmodule.exports = function(req, res) {\n "
  },
  {
    "path": "biz/webui/cgi-bin/get-custom-certs-info.js",
    "chars": 168,
    "preview": "var getCustomCertsInfo = require('../../../lib/https/ca').getCustomCertsInfo;\n// 给第三方用的,不能删除\nmodule.exports = function(r"
  },
  {
    "path": "biz/webui/cgi-bin/get-data.js",
    "chars": 2923,
    "preview": "var proxy = require('../lib/proxy');\nvar util = require('./util');\nvar config = require('../../../lib/config');\nvar rule"
  },
  {
    "path": "biz/webui/cgi-bin/get-frames.js",
    "chars": 313,
    "preview": "var proxy = require('../lib/proxy');\nvar socketMgr = proxy.socketMgr;\n\nmodule.exports = function(req, res) {\n  var frame"
  },
  {
    "path": "biz/webui/cgi-bin/get-session.js",
    "chars": 691,
    "preview": "var proxy = require('../lib/proxy');\n\nvar emptyArr = [];\nvar parseArray = function(str) {\n  try {\n    str = JSON.parse(s"
  },
  {
    "path": "biz/webui/cgi-bin/hide-https-connects.js",
    "chars": 78,
    "preview": "module.exports = function(req, res) {\n  res.json({ec: 0, em: 'success'});\n};\n\n"
  },
  {
    "path": "biz/webui/cgi-bin/https-status.js",
    "chars": 229,
    "preview": "var properties = require('../../../lib/rules/util').properties;\n\nmodule.exports = function(req, res) {\n  res.json({\n    "
  },
  {
    "path": "biz/webui/cgi-bin/import-remote.js",
    "chars": 1145,
    "preview": "var util = require('../../../lib/util');\nvar loadService = require('../lib/proxy').loadService;\n\nvar MAX_LEN = 1024 * 10"
  },
  {
    "path": "biz/webui/cgi-bin/init.js",
    "chars": 1875,
    "preview": "var getRules = require('./rules');\nvar getValues = require('./values');\nvar util = require('./util');\nvar config = requi"
  },
  {
    "path": "biz/webui/cgi-bin/intercept-https-connects.js",
    "chars": 212,
    "preview": "var properties = require('../../../lib/rules/util').properties;\n\nmodule.exports = function(req, res) {\n  properties.setE"
  },
  {
    "path": "biz/webui/cgi-bin/log/set.js",
    "chars": 168,
    "preview": "var proxy = require('../../lib/proxy');\n\nmodule.exports = function(req, res) {\n  proxy.addLog(req.query);\n  res.setHeade"
  },
  {
    "path": "biz/webui/cgi-bin/plugins/add-registry.js",
    "chars": 161,
    "preview": "var pluginMgr = require('../../lib/proxy').pluginMgr;\n\nmodule.exports = function(req, res) {\n  pluginMgr.addRegistry(req"
  },
  {
    "path": "biz/webui/cgi-bin/plugins/disable-all-plugins.js",
    "chars": 197,
    "preview": "var pluginMgr = require('../../lib/proxy').pluginMgr;\n\nmodule.exports = function(req, res) {\n  pluginMgr.disableAllPlugi"
  },
  {
    "path": "biz/webui/cgi-bin/plugins/disable-plugin.js",
    "chars": 483,
    "preview": "var properties = require('../../../../lib/rules/util').properties;\nvar pluginMgr = require('../../lib/proxy').pluginMgr;"
  },
  {
    "path": "biz/webui/cgi-bin/plugins/get-plugins.js",
    "chars": 353,
    "preview": "var properties = require('../../../../lib/rules/util').properties;\nvar pluginMgr = require('../../lib/proxy').pluginMgr;"
  },
  {
    "path": "biz/webui/cgi-bin/plugins/is-enable.js",
    "chars": 280,
    "preview": "var pluginMgr = require('../../lib/proxy').pluginMgr;\nvar config = require('../../../../lib/config');\n\nmodule.exports = "
  },
  {
    "path": "biz/webui/cgi-bin/plugins/registry-list.js",
    "chars": 154,
    "preview": "var pluginMgr = require('../../lib/proxy').pluginMgr;\n\nmodule.exports = function(req, res) {\n  res.json({ ec: 0, list: p"
  },
  {
    "path": "biz/webui/cgi-bin/plugins/uninstall.js",
    "chars": 720,
    "preview": "var path = require('path');\nvar fs = require('fs');\nvar pluginMgr = require('../../lib/proxy').pluginMgr;\n\nmodule.export"
  },
  {
    "path": "biz/webui/cgi-bin/plugins/update-rules.js",
    "chars": 252,
    "preview": "var config = require('../../../../lib/config');\nvar pluginMgr = require('../../lib/proxy').pluginMgr;\n\nmodule.exports = "
  },
  {
    "path": "biz/webui/cgi-bin/reset-local-address.js",
    "chars": 148,
    "preview": "var util = require('../../../lib/util');\n\nmodule.exports = function(req, res) {\n  util.localIpCache.reset();\n  res.json("
  },
  {
    "path": "biz/webui/cgi-bin/rootca.js",
    "chars": 392,
    "preview": "var properties = require('../../../lib/rules/util').properties;\nvar getRootCAFile = require('../../../lib/https/ca').get"
  },
  {
    "path": "biz/webui/cgi-bin/rules/account.js",
    "chars": 165,
    "preview": "var getAccountRules = require('../../../../lib/rules/util').getAccountRules;\n\nmodule.exports = function(_, res) {\n  res."
  },
  {
    "path": "biz/webui/cgi-bin/rules/add.js",
    "chars": 1220,
    "preview": "var rules = require('../../../../lib/rules/util').rules;\nvar recycleBin = require('../../../../lib/rules/util').rules.re"
  },
  {
    "path": "biz/webui/cgi-bin/rules/allow-multiple-choice.js",
    "chars": 350,
    "preview": "var properties = require('../../../../lib/rules/util').properties;\nvar proxy = require('../../lib/proxy');\n\nmodule.expor"
  },
  {
    "path": "biz/webui/cgi-bin/rules/disable-all-rules.js",
    "chars": 193,
    "preview": "var rules = require('../../../../lib/rules/util').rules;\n\nmodule.exports = function(req, res) {\n  rules.disableAllRules("
  },
  {
    "path": "biz/webui/cgi-bin/rules/disable-default.js",
    "chars": 248,
    "preview": "var rules = require('../../../../lib/rules/util').rules;\n\nmodule.exports = function(req, res) {\n  rules.disableDefault()"
  },
  {
    "path": "biz/webui/cgi-bin/rules/enable-back-rules-first.js",
    "chars": 198,
    "preview": "var rules = require('../../../../lib/rules/util').rules;\n\nmodule.exports = function(req, res) {\n  rules.enableBackRulesF"
  },
  {
    "path": "biz/webui/cgi-bin/rules/enable-default.js",
    "chars": 302,
    "preview": "var rules = require('../../../../lib/rules/util').rules;\n\nmodule.exports = function(req, res) {\n  rules.enableDefault();"
  },
  {
    "path": "biz/webui/cgi-bin/rules/enabled.js",
    "chars": 238,
    "preview": "var rules = require('../../../../lib/rules/util').rules;\nvar util = require('../util');\n\nmodule.exports = function(req, "
  },
  {
    "path": "biz/webui/cgi-bin/rules/export.js",
    "chars": 974,
    "preview": "var rules = require('../../../../lib/rules/util').rules;\nvar util = require('../util');\n\nmodule.exports = function(req, "
  },
  {
    "path": "biz/webui/cgi-bin/rules/import.js",
    "chars": 412,
    "preview": "var get = require('./index');\nvar addRules = require('../../../../lib/rules/util').addRules;\nvar util = require('../util"
  },
  {
    "path": "biz/webui/cgi-bin/rules/index.js",
    "chars": 478,
    "preview": "var rules = require('../../../../lib/rules/util').rules;\nvar properties = require('../../../../lib/rules/util').properti"
  },
  {
    "path": "biz/webui/cgi-bin/rules/list.js",
    "chars": 137,
    "preview": "var get = require('./index');\nvar util = require('../util');\n\nmodule.exports = function(req, res) {\n  util.sendGzip(req,"
  },
  {
    "path": "biz/webui/cgi-bin/rules/list2.js",
    "chars": 580,
    "preview": "var get = require('./index');\n\nmodule.exports = function(req, res) {\n  var rules = get();\n  var data;\n  if (req.query.or"
  },
  {
    "path": "biz/webui/cgi-bin/rules/move-to.js",
    "chars": 281,
    "preview": "var rules = require('../../../../lib/rules/util').rules;\n\nmodule.exports = function(req, res) {\n  var body = req.body;\n "
  },
  {
    "path": "biz/webui/cgi-bin/rules/project.js",
    "chars": 1112,
    "preview": "var rules = require('../../../../lib/rules/util').rules;\n\nvar DEFAULT_GROUP = '\\rothers';\n\nmodule.exports = function(req"
  },
  {
    "path": "biz/webui/cgi-bin/rules/recycle/list.js",
    "chars": 225,
    "preview": "var recycleBin = require('../../../../../lib/rules/util').rules.recycleBin;\nvar util = require('../../util');\n\nmodule.ex"
  },
  {
    "path": "biz/webui/cgi-bin/rules/recycle/remove.js",
    "chars": 212,
    "preview": "var recycleBin = require('../../../../../lib/rules/util').rules.recycleBin;\n\nmodule.exports = function(req, res) {\n  rec"
  },
  {
    "path": "biz/webui/cgi-bin/rules/recycle/view.js",
    "chars": 236,
    "preview": "var recycleBin = require('../../../../../lib/rules/util').rules.recycleBin;\n\nmodule.exports = function(req, res) {\n  var"
  },
  {
    "path": "biz/webui/cgi-bin/rules/remove.js",
    "chars": 170,
    "preview": "var util = require('../../../../lib/rules/util');\n\nmodule.exports = function(req, res) {\n  util.removeBatch(util.rules, "
  },
  {
    "path": "biz/webui/cgi-bin/rules/rename.js",
    "chars": 214,
    "preview": "var rules = require('../../../../lib/rules/util').rules;\n\nmodule.exports = function(req, res) {\n  var body = req.body;\n "
  },
  {
    "path": "biz/webui/cgi-bin/rules/select.js",
    "chars": 575,
    "preview": "var rules = require('../../../../lib/rules/util').rules;\n\nmodule.exports = function(req, res) {\n  var body = req.body;\n "
  },
  {
    "path": "biz/webui/cgi-bin/rules/set-sys-hosts.js",
    "chars": 223,
    "preview": "var rules = require('../../../../lib/rules/util').rules;\n\nmodule.exports = function(req, res) {\n  rules.setSysHosts(req."
  },
  {
    "path": "biz/webui/cgi-bin/rules/unselect.js",
    "chars": 299,
    "preview": "var rules = require('../../../../lib/rules/util').rules;\n\nmodule.exports = function(req, res) {\n  rules.add(req.body.nam"
  },
  {
    "path": "biz/webui/cgi-bin/server-info.js",
    "chars": 126,
    "preview": "var util = require('./util');\n\nmodule.exports = function(req, res) {\n  res.json({ec: 0, server: util.getServerInfo(req)}"
  },
  {
    "path": "biz/webui/cgi-bin/set-custom-column.js",
    "chars": 540,
    "preview": "var util = require('../../../lib/util');\nvar properties = require('../../../lib/rules/util').properties;\n\n\nfunction upda"
  },
  {
    "path": "biz/webui/cgi-bin/set-dns-order.js",
    "chars": 299,
    "preview": "var properties = require('../../../lib/rules/util').properties;\nvar config = require('../../../lib/config');\n\nmodule.exp"
  },
  {
    "path": "biz/webui/cgi-bin/socket/abort.js",
    "chars": 231,
    "preview": "var proxy = require('../../lib/proxy');\n\nvar socketMgr = proxy.socketMgr;\n\nmodule.exports = function(req, res) {\n  var r"
  },
  {
    "path": "biz/webui/cgi-bin/socket/change-status.js",
    "chars": 153,
    "preview": "var socketMgr = require('../../lib/proxy').socketMgr;\n\nmodule.exports = function(req, res) {\n  socketMgr.changeStatus(re"
  },
  {
    "path": "biz/webui/cgi-bin/socket/data.js",
    "chars": 185,
    "preview": "var socketMgr = require('../../lib/proxy').socketMgr;\n\nmodule.exports = function(req, res) {\n  var result = socketMgr.se"
  },
  {
    "path": "biz/webui/cgi-bin/status.js",
    "chars": 254,
    "preview": "var config = require('../../../lib/config');\n\nmodule.exports = function(_, res) {\n  res.json({\n    storage: config.stora"
  },
  {
    "path": "biz/webui/cgi-bin/top.js",
    "chars": 109,
    "preview": "var proc = require('../../../lib/util/process');\n\nmodule.exports = function(req, res) {\n  res.json(proc);\n};\n"
  },
  {
    "path": "biz/webui/cgi-bin/util.js",
    "chars": 4342,
    "preview": "var util = require('../../../lib/util');\nvar config = require('../../../lib/config');\nvar proc = require('../../../lib/u"
  },
  {
    "path": "biz/webui/cgi-bin/values/add.js",
    "chars": 916,
    "preview": "var values = require('../../../../lib/rules/util').values;\nvar recycleBin = require('../../../../lib/rules/util').values"
  },
  {
    "path": "biz/webui/cgi-bin/values/export.js",
    "chars": 812,
    "preview": "var values = require('../../../../lib/rules/util').values;\nvar util = require('../util');\n\nmodule.exports = function(req"
  },
  {
    "path": "biz/webui/cgi-bin/values/get.js",
    "chars": 365,
    "preview": "var values = require('../../../../lib/rules/util').values;\nvar properties = require('../../../../lib/rules/util').proper"
  },
  {
    "path": "biz/webui/cgi-bin/values/import.js",
    "chars": 415,
    "preview": "var get = require('./index');\nvar util = require('../util');\nvar addValues = require('../../../../lib/rules/util').addVa"
  },
  {
    "path": "biz/webui/cgi-bin/values/index.js",
    "chars": 175,
    "preview": "var rulesUtil = require('../../../../lib/rules/util');\nvar values = rulesUtil.values;\n\nmodule.exports = function get() {"
  },
  {
    "path": "biz/webui/cgi-bin/values/list.js",
    "chars": 137,
    "preview": "var get = require('./index');\nvar util = require('../util');\n\nmodule.exports = function(req, res) {\n  util.sendGzip(req,"
  },
  {
    "path": "biz/webui/cgi-bin/values/list2.js",
    "chars": 449,
    "preview": "var get = require('./index');\n\nmodule.exports = function(req, res) {\n  var data;\n  if (req.query.order) {\n    data = [];"
  },
  {
    "path": "biz/webui/cgi-bin/values/move-to.js",
    "chars": 261,
    "preview": "var values = require('../../../../lib/rules/util').values;\n\nmodule.exports = function(req, res) {\n  var body = req.body;"
  },
  {
    "path": "biz/webui/cgi-bin/values/recycle/list.js",
    "chars": 226,
    "preview": "var recycleBin = require('../../../../../lib/rules/util').values.recycleBin;\nvar util = require('../../util');\n\nmodule.e"
  },
  {
    "path": "biz/webui/cgi-bin/values/recycle/remove.js",
    "chars": 213,
    "preview": "var recycleBin = require('../../../../../lib/rules/util').values.recycleBin;\n\nmodule.exports = function(req, res) {\n  re"
  },
  {
    "path": "biz/webui/cgi-bin/values/recycle/view.js",
    "chars": 237,
    "preview": "var recycleBin = require('../../../../../lib/rules/util').values.recycleBin;\n\nmodule.exports = function(req, res) {\n  va"
  },
  {
    "path": "biz/webui/cgi-bin/values/remove.js",
    "chars": 171,
    "preview": "var util = require('../../../../lib/rules/util');\n\nmodule.exports = function(req, res) {\n  util.removeBatch(util.values,"
  },
  {
    "path": "biz/webui/cgi-bin/values/rename.js",
    "chars": 217,
    "preview": "var values = require('../../../../lib/rules/util').values;\n\nmodule.exports = function(req, res) {\n  var body = req.body;"
  },
  {
    "path": "biz/webui/cgi-bin/values/value.js",
    "chars": 151,
    "preview": "var values = require('../../../../lib/rules/util').values;\n\nmodule.exports = function(req, res) {\n  res.json({ value: va"
  },
  {
    "path": "biz/webui/htdocs/editor.html",
    "chars": 2470,
    "preview": "<!DOCTYPE html>\n<html data-theme=\"light\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"google\" value=\"notranslate\">\n<link r"
  },
  {
    "path": "biz/webui/htdocs/index.html",
    "chars": 361,
    "preview": "<!DOCTYPE html>\n<html data-theme=\"light\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"google\" value=\"notranslate\">\n<link r"
  },
  {
    "path": "biz/webui/htdocs/js/decode.js",
    "chars": 6388,
    "preview": "!function(r){function t(e){if(n[e])return n[e].exports;var o=n[e]={exports:{},id:e,loaded:!1};return r[e].call(o.exports"
  },
  {
    "path": "biz/webui/htdocs/js/index.js",
    "chars": 1955502,
    "preview": "!function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return e[r].call(o.exports"
  },
  {
    "path": "biz/webui/htdocs/preview.html",
    "chars": 8721,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n  <title>PREVIEW</title>\n</head>\n<body style=\"overscroll-behavior-x: none;\">\n  <script>\n  "
  },
  {
    "path": "biz/webui/htdocs/src/css/about.css",
    "chars": 400,
    "preview": ".w-about-dialog .modal-dialog {\n  width: 390px;\n}\n.w-about-dialog .modal-dialog .modal-body {\n  padding-bottom: 15px;\n}\n"
  },
  {
    "path": "biz/webui/htdocs/src/css/base.css",
    "chars": 11572,
    "preview": ":root {\n  --z-max: 1000000100;\n  --z-modal: 1051;\n  --z-modal-max: 1059;\n  --z-cm: 999999;\n  --z-menu: 1001;\n  --z-ctx-m"
  },
  {
    "path": "biz/webui/htdocs/src/css/btn-group.css",
    "chars": 949,
    "preview": ".w-tabs-sm {\n  border-top: 1px solid var(--c-border);\n  border-bottom: 1px solid var(--c-border);\n  width: 100%;\n}\n.w-ta"
  },
  {
    "path": "biz/webui/htdocs/src/css/certs.css",
    "chars": 969,
    "preview": ".w-certs-dialog {\n  z-index: var(--z-modal);\n}\n\n.w-certs-dialog .w-help-icon {\n  font-size: 15px;\n  margin-top: -2px;\n}\n"
  },
  {
    "path": "biz/webui/htdocs/src/css/composer.css",
    "chars": 11898,
    "preview": ".w-detail-com {\n  overflow-x: hidden;\n  overflow-y: auto;\n}\n.w-detail-com textarea {\n  display: block;\n  width: 100%;\n  "
  },
  {
    "path": "biz/webui/htdocs/src/css/context-menu.css",
    "chars": 2326,
    "preview": "/* Context Menu Style by marvin1023 */\n.w-ctx-menu {\n  position: absolute;\n  z-index: var(--z-ctx-menu);\n}\n\n.w-ctx-menu-"
  },
  {
    "path": "biz/webui/htdocs/src/css/detail.css",
    "chars": 2180,
    "preview": ".w-detail {\n  border-left: 1px solid var(--c-border);\n  overflow-x: auto;\n  overflow-y: hidden;\n}\n.w-detail-ctn {\n  posi"
  },
  {
    "path": "biz/webui/htdocs/src/css/divider.css",
    "chars": 923,
    "preview": ".w-divider-left,\n.w-divider-right {\n  overflow: hidden;\n  position: relative;\n}\n.w-divider-con.box > .w-divider-right {\n"
  },
  {
    "path": "biz/webui/htdocs/src/css/dropdown.css",
    "chars": 796,
    "preview": ".w-dropdown-text {\n  max-width: 300px;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n  cursor: p"
  },
  {
    "path": "biz/webui/htdocs/src/css/editor-settings.css",
    "chars": 540,
    "preview": ".w-editor-settings label,\n.w-editor-settings-box label {\n  font-weight: normal;\n  white-space: nowrap;\n}\n.w-editor-setti"
  },
  {
    "path": "biz/webui/htdocs/src/css/editor.css",
    "chars": 614,
    "preview": ".CodeMirror-hints li.CodeMirror-hint-active:after {\n  content: 'F1';\n  position: absolute;\n  right: 0;\n  font-size: 12px"
  },
  {
    "path": "biz/webui/htdocs/src/css/files-dialog.css",
    "chars": 497,
    "preview": ".w-files-dialog .modal-dialog {\n  width: 900px;\n}\n\n.w-files-order {\n  width: 36px;\n}\n.w-files-date {\n  width: 205px;\n}\n."
  },
  {
    "path": "biz/webui/htdocs/src/css/filter-input.css",
    "chars": 2333,
    "preview": ".w-filter-con {\n  position: relative;\n}\n.w-filter-con .w-clear-input {\n  position: absolute;\n  right: 5px;\n  bottom: 10p"
  },
  {
    "path": "biz/webui/htdocs/src/css/frames.css",
    "chars": 3994,
    "preview": ".w-frames {\n  font-size: 12px;\n  min-width: 560px;\n}\n.w-frames-action {\n  background: var(--b-title);\n  position: relati"
  },
  {
    "path": "biz/webui/htdocs/src/css/iframe-dialog.css",
    "chars": 319,
    "preview": "\n.w-iframe-dialog .modal-dialog {\n  width: max(calc(100% - 240px), 720px);\n}\n\n.w-iframe-dialog .modal-body {\n  padding: "
  },
  {
    "path": "biz/webui/htdocs/src/css/iframe.css",
    "chars": 267,
    "preview": ".w-iframe {\n  position: relative;\n  min-width: 560px;\n}\n\n.w-iframe > iframe.fill {\n  display: block;\n  width: 100%;\n  he"
  },
  {
    "path": "biz/webui/htdocs/src/css/image-view.css",
    "chars": 626,
    "preview": ".w-image-view {\n  font-size: 0;\n  white-space: nowrap;\n  overflow: auto;\n  text-align: center;\n  position: relative;\n}\n."
  },
  {
    "path": "biz/webui/htdocs/src/css/import-dialog.css",
    "chars": 318,
    "preview": ".w-ie-dialog .modal-dialog {\n  width: 600px;\n}\n\n.w-ie-dialog .modal-body {\n  background-color: var(--b-bar);\n  padding: "
  },
  {
    "path": "biz/webui/htdocs/src/css/index.css",
    "chars": 9046,
    "preview": ".w-menu {\n  height: 34px;\n  border-bottom: 1px solid var(--c-border);\n  background: var(--b-title);\n  padding-right: 80p"
  },
  {
    "path": "biz/webui/htdocs/src/css/json-viewer.css",
    "chars": 246,
    "preview": ".w-props-wrap:hover .w-textarea-bar {\n  display: inline-block;\n}\n.w-json-viewer-str,\n.w-json-viewer-tree {\n  padding: 5p"
  },
  {
    "path": "biz/webui/htdocs/src/css/kv.css",
    "chars": 665,
    "preview": ".w-kv-dialog {\n  z-index: calc(var(--z-modal) + 1);\n}\n\n.w-kv-dialog .modal-dialog {\n  width: 720px;\n}\n.w-kv-name {\n  wid"
  },
  {
    "path": "biz/webui/htdocs/src/css/large-dialog.css",
    "chars": 1419,
    "preview": ".w-large-dialog .modal-dialog {\n  width: calc(100% - 100px);\n  height: calc(100% - 60px);\n  min-width: 960px;\n  min-heig"
  },
  {
    "path": "biz/webui/htdocs/src/css/list-dialog.css",
    "chars": 2137,
    "preview": ".w-list-wrapper label {\n  line-height: 26px;\n  width: 200px;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-spac"
  },
  {
    "path": "biz/webui/htdocs/src/css/list.css",
    "chars": 3177,
    "preview": ".w-divider-con .w-divider {\n  border: none;\n}\n.w-list-data {\n  background: var(--b-bar);\n  overflow-x: hidden;\n  overflo"
  },
  {
    "path": "biz/webui/htdocs/src/css/menu-item.css",
    "chars": 1035,
    "preview": ".w-menu-item {\n  position: absolute;\n  background: var(--b-default);\n  border: 1px solid var(--c-border);\n  z-index: var"
  },
  {
    "path": "biz/webui/htdocs/src/css/message.css",
    "chars": 191,
    "preview": ".w-message {\n  position: fixed;\n  top: 30px;\n  left: 50%;\n  z-index: calc(var(--z-max) + 2);\n  padding: 8px 20px !import"
  },
  {
    "path": "biz/webui/htdocs/src/css/modal.css",
    "chars": 56,
    "preview": ".w-dialog-for-plguin .modal-header {\n  display: none;\n}\n"
  },
  {
    "path": "biz/webui/htdocs/src/css/network-settings.css",
    "chars": 2841,
    "preview": ".w-ns-dialog fieldset {\n  border: 1px solid var(--c-border);\n  padding-bottom: 10px;\n}\n.w-ns-dialog legend {\n  border: n"
  },
  {
    "path": "biz/webui/htdocs/src/css/online.css",
    "chars": 2043,
    "preview": ".w-online-dialog .modal-dialog {\n  width: 320px;\n}\n.w-online-info,\n.w-online-dns {\n  display: none;\n}\n.w-online-ctn h5 {"
  },
  {
    "path": "biz/webui/htdocs/src/css/override.css",
    "chars": 6204,
    "preview": ".table-hover>tbody>tr:hover {\n  background-color: var(--b-hover);\n}\n\n.nav-tabs {\n  border-bottom: 1px solid var(--c-bord"
  },
  {
    "path": "biz/webui/htdocs/src/css/overview.css",
    "chars": 877,
    "preview": ".w-detail-overview > .w-props-wrap:last-child {\n  border-top: 1px solid var(--c-border);\n}\n.w-detail-overview-title {\n  "
  },
  {
    "path": "biz/webui/htdocs/src/css/plugins-mgr.css",
    "chars": 467,
    "preview": ".w-plugins-mgr-dialog {\n  z-index: var(--z-modal-max);\n}\n\n.w-plugins-mgr-dialog .modal-content {\n  width: 380px;\n}\n\n.w-p"
  },
  {
    "path": "biz/webui/htdocs/src/css/plugins.css",
    "chars": 5062,
    "preview": ".w-nav-tabs {\n  font-size: 13px;\n}\n.w-nav-tabs > .nav-tabs {\n  padding-left: 2px;\n  padding-top: 5px;\n  background: var("
  },
  {
    "path": "biz/webui/htdocs/src/css/properties.css",
    "chars": 1739,
    "preview": ".w-props-wrap {\n  position: relative;\n}\n.w-props-source {\n  padding: 5px 10px;\n}\n.w-props-view-source .w-props-parsed {\n"
  },
  {
    "path": "biz/webui/htdocs/src/css/props-editor.css",
    "chars": 2235,
    "preview": ".w-props-editor {\n  list-style: none;\n  margin: 0;\n  padding: 0;\n  overflow-y: auto;\n  overflow-x: hidden;\n}\n\n.w-props-e"
  },
  {
    "path": "biz/webui/htdocs/src/css/record-btn.css",
    "chars": 414,
    "preview": ".w-switch-btn .glyphicon-stop {\n  color: var(--c-risk);\n}\n\n.w-switch-btn .w-disabled .glyphicon-stop,\n.w-switch-btn .w-p"
  },
  {
    "path": "biz/webui/htdocs/src/css/req-data.css",
    "chars": 7935,
    "preview": ".w-req-data-con {\n  overflow-x: auto;\n}\n.w-req-data-ctn {\n  overflow-x: auto;\n  overflow-y: hidden;\n  position: relative"
  },
  {
    "path": "biz/webui/htdocs/src/css/req-detail.css",
    "chars": 986,
    "preview": ".w-detail-request textarea {\n  padding: 5px;\n  border: none;\n}\n\n.w-detail-request-headers,\n.w-detail-request-cookies,\n.w"
  },
  {
    "path": "biz/webui/htdocs/src/css/res-detail.css",
    "chars": 463,
    "preview": ".w-detail-res textarea {\n  padding: 5px;\n  border: none;\n}\n.w-detail-res-headers,\n.w-detail-res-cookies {\n  overflow: au"
  },
  {
    "path": "biz/webui/htdocs/src/css/service.css",
    "chars": 225,
    "preview": ".w-service-btn {\n  font-weight: bold;\n}\n\n.w-service-btn .w-disabled {\n  cursor: pointer!important;\n}\n\n.w-large-dialog.w-"
  },
  {
    "path": "biz/webui/htdocs/src/css/sync-dialog.css",
    "chars": 385,
    "preview": ".w-sync-dialog .modal-dialog {\n  width: 420px;\n}\n\n.w-sync-dialog .modal-body .btn {\n  display: block;\n  width: 398px;\n  "
  },
  {
    "path": "biz/webui/htdocs/src/css/table.css",
    "chars": 1055,
    "preview": ".w-table > thead > tr > th {\n  white-space: nowrap;\n  background: var(--b-bar);\n  border-bottom: 1px;\n  font-weight: 500"
  },
  {
    "path": "biz/webui/htdocs/src/css/textarea.css",
    "chars": 1796,
    "preview": ".w-textarea {\n  position: relative;\n}\n.w-textarea-bar {\n  display: none;\n  position: absolute;\n  z-index: 1;\n  border-ra"
  },
  {
    "path": "biz/webui/htdocs/src/css/theme.css",
    "chars": 3446,
    "preview": "\n[data-theme=\"dark\"]:root {\n  color-scheme: dark;\n  /* 颜色变量 */\n  --c-default: #f0f0f0;\n  --c-btn: #eee;\n  --c-active: #1"
  },
  {
    "path": "biz/webui/htdocs/src/css/timeline.css",
    "chars": 1289,
    "preview": ".w-timeline ul,\n.w-timeline li {\n  list-style: none;\n  margin: 0;\n  padding: 0;\n  white-space: nowrap;\n  font-size: 0;\n "
  },
  {
    "path": "biz/webui/htdocs/src/css/tools.css",
    "chars": 8737,
    "preview": ".w-tools {\n  position: relative;\n  min-width: 560px;\n}\n.w-tools ul,\n.w-tools li {\n  list-style: none;\n  padding: 0;\n  ma"
  },
  {
    "path": "biz/webui/htdocs/src/js/about.js",
    "chars": 6191,
    "preview": "require('../css/about.css');\nvar React = require('react');\nvar Dialog = require('./dialog');\nvar dataCenter = require('."
  },
  {
    "path": "biz/webui/htdocs/src/js/base-css.js",
    "chars": 199,
    "preview": "require('bootstrap/dist/css/bootstrap.css');\nrequire('../css/base.css');\nrequire('../css/override.css');\nwindow.jQuery ="
  },
  {
    "path": "biz/webui/htdocs/src/js/bridge.js",
    "chars": 5335,
    "preview": "var qrCode = require('qrcode');\nvar $ = require('jquery');\nvar message = require('./message');\nvar createCgi = require('"
  },
  {
    "path": "biz/webui/htdocs/src/js/btn-group.js",
    "chars": 2207,
    "preview": "require('../css/btn-group.css');\nvar React = require('react');\nvar util = require('./util');\nvar Icon = require('./icon'"
  },
  {
    "path": "biz/webui/htdocs/src/js/certs-info-dialog.js",
    "chars": 10741,
    "preview": "require('../css/certs.css');\nvar React = require('react');\nvar ReactDOM = require('react-dom');\nvar util = require('./ut"
  },
  {
    "path": "biz/webui/htdocs/src/js/cgi.js",
    "chars": 1842,
    "preview": "var $ = require('jquery');\nvar util = require('./util');\n\nvar auth = util.getQuery().authorization;\n\nfunction createCgi("
  },
  {
    "path": "biz/webui/htdocs/src/js/close-btn.js",
    "chars": 544,
    "preview": "var React = require('react');\n\nvar CloseBtn = React.createClass({\n  shouldComponentUpdate: function (nextProps) {\n    va"
  },
  {
    "path": "biz/webui/htdocs/src/js/columns.js",
    "chars": 9517,
    "preview": "var $ = require('jquery');\nvar React = require('react');\nvar dataCenter = require('./data-center');\nvar events = require"
  },
  {
    "path": "biz/webui/htdocs/src/js/components/json/index.js",
    "chars": 80,
    "preview": "exports.parse = require('./parse');\nexports.stringify = require('./stringify');\n"
  },
  {
    "path": "biz/webui/htdocs/src/js/components/json/parse.js",
    "chars": 8042,
    "preview": "/*\n    json_parse.js\n    2016-05-02\n\n    Public Domain.\n\n    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.\n\n  "
  },
  {
    "path": "biz/webui/htdocs/src/js/components/json/stringify.js",
    "chars": 13300,
    "preview": "//  json2.js\n//  2017-06-12\n//  Public Domain.\n//  NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.\n\n//  USE YOUR"
  },
  {
    "path": "biz/webui/htdocs/src/js/components/react-json-tree/ItemRange.js",
    "chars": 2500,
    "preview": "'use strict';\n\nexports.__esModule = true;\n\nvar _extends2 = require('babel-runtime/helpers/extends');\n\nvar _extends3 = _i"
  },
  {
    "path": "biz/webui/htdocs/src/js/components/react-json-tree/JSONArrayNode.js",
    "chars": 1358,
    "preview": "'use strict';\n\nexports.__esModule = true;\n\nvar _extends2 = require('babel-runtime/helpers/extends');\n\nvar _extends3 = _i"
  },
  {
    "path": "biz/webui/htdocs/src/js/components/react-json-tree/JSONArrow.js",
    "chars": 1099,
    "preview": "'use strict';\n\nexports.__esModule = true;\n\nvar _extends2 = require('babel-runtime/helpers/extends');\n\nvar _extends3 = _i"
  },
  {
    "path": "biz/webui/htdocs/src/js/components/react-json-tree/JSONIterableNode.js",
    "chars": 2349,
    "preview": "'use strict';\n\nexports.__esModule = true;\n\nvar _extends2 = require('babel-runtime/helpers/extends');\n\nvar _extends3 = _i"
  },
  {
    "path": "biz/webui/htdocs/src/js/components/react-json-tree/JSONNestedNode.js",
    "chars": 7984,
    "preview": "'use strict';\n\nexports.__esModule = true;\n\nvar _stringify = require('babel-runtime/core-js/json/stringify');\n\nvar _strin"
  },
  {
    "path": "biz/webui/htdocs/src/js/components/react-json-tree/JSONNode.js",
    "chars": 5211,
    "preview": "'use strict';\n\nexports.__esModule = true;\n\nvar _extends2 = require('babel-runtime/helpers/extends');\n\nvar _extends3 = _i"
  },
  {
    "path": "biz/webui/htdocs/src/js/components/react-json-tree/JSONObjectNode.js",
    "chars": 1656,
    "preview": "'use strict';\n\nexports.__esModule = true;\n\nvar _extends2 = require('babel-runtime/helpers/extends');\n\nvar _extends3 = _i"
  },
  {
    "path": "biz/webui/htdocs/src/js/components/react-json-tree/JSONValueNode.js",
    "chars": 1569,
    "preview": "'use strict';\n\nexports.__esModule = true;\n\nvar _extends2 = require('babel-runtime/helpers/extends');\n\nvar _extends3 = _i"
  },
  {
    "path": "biz/webui/htdocs/src/js/components/react-json-tree/createStylingFromTheme.js",
    "chars": 6068,
    "preview": "'use strict';\n\nexports.__esModule = true;\n\nvar _extends2 = require('babel-runtime/helpers/extends');\n\nvar _extends3 = _i"
  },
  {
    "path": "biz/webui/htdocs/src/js/components/react-json-tree/getCollectionEntries.js",
    "chars": 4696,
    "preview": "'use strict';\n\nexports.__esModule = true;\n\nvar _getIterator2 = require('babel-runtime/core-js/get-iterator');\n\nvar _getI"
  },
  {
    "path": "biz/webui/htdocs/src/js/components/react-json-tree/index.js",
    "chars": 11001,
    "preview": "'use strict';\n\nexports.__esModule = true;\n\nvar _objectWithoutProperties2 = require('babel-runtime/helpers/objectWithoutP"
  },
  {
    "path": "biz/webui/htdocs/src/js/components/react-json-tree/objType.js",
    "chars": 787,
    "preview": "'use strict';\n\nexports.__esModule = true;\n\nvar _iterator = require('babel-runtime/core-js/symbol/iterator');\n\nvar _itera"
  },
  {
    "path": "biz/webui/htdocs/src/js/components/react-json-tree/themes/solarized.js",
    "chars": 559,
    "preview": "'use strict';\n\nexports.__esModule = true;\nexports['default'] = {\n  scheme: 'solarized',\n  author: 'ethan schoonover (htt"
  },
  {
    "path": "biz/webui/htdocs/src/js/components/react-json-tree/utils/hexToRgb.js",
    "chars": 305,
    "preview": "'use strict';\n\nexports.__esModule = true;\n\nexports['default'] = function (hex) {\n  var result = /^#?([a-f\\d]{2})([a-f\\d]"
  },
  {
    "path": "biz/webui/htdocs/src/js/composer-list.js",
    "chars": 2954,
    "preview": "var React = require('react');\nvar Composer = require('./composer');\nvar util = require('./util');\nvar LazyInit = require"
  },
  {
    "path": "biz/webui/htdocs/src/js/composer.js",
    "chars": 64275,
    "preview": "require('../css/composer.css');\nvar React = require('react');\nvar ReactDOM = require('react-dom');\nvar $ = require('jque"
  },
  {
    "path": "biz/webui/htdocs/src/js/console.js",
    "chars": 10596,
    "preview": "var $ = require('jquery');\nvar React = require('react');\nvar ReactDOM = require('react-dom');\n\nvar JSONTree = require('."
  },
  {
    "path": "biz/webui/htdocs/src/js/context-menu.js",
    "chars": 6400,
    "preview": "require('../css/context-menu.css');\nvar $ = require('jquery');\nvar React = require('react');\nvar ReactDOM = require('rea"
  },
  {
    "path": "biz/webui/htdocs/src/js/cookies-dialog.js",
    "chars": 2437,
    "preview": "var React = require('react');\nvar Dialog = require('./dialog');\nvar CloseBtn = require('./close-btn');\n\nvar CookiesDialo"
  },
  {
    "path": "biz/webui/htdocs/src/js/copy-btn.js",
    "chars": 701,
    "preview": "var React = require('react');\n\nvar CopyBtn = React.createClass({\n  getInitialState: function () {\n    return {};\n  },\n  "
  },
  {
    "path": "biz/webui/htdocs/src/js/data-center.js",
    "chars": 57768,
    "preview": "var $ = require('jquery');\nvar createCgiObj = require('./cgi');\nvar util = require('./util');\nvar NetworkModal = require"
  },
  {
    "path": "biz/webui/htdocs/src/js/decode.js",
    "chars": 666,
    "preview": "var toByteArray = require('base64-js').toByteArray;\nvar base64Decode = require('js-base64').Base64.decode;\nvar isUtf8 = "
  },
  {
    "path": "biz/webui/htdocs/src/js/detail.js",
    "chars": 8232,
    "preview": "require('../css/detail.css');\nvar $ = require('jquery');\nvar React = require('react');\nvar ReactDOM = require('react-dom"
  }
]

// ... and 637 more files (download for full content)

About this extraction

This page contains the full source code of the avwo/whistle GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 837 files (5.0 MB), approximately 1.3M tokens, and a symbol index with 3131 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!