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 ================================================
# whistle [](https://npmjs.org/package/whistle) [](http://nodejs.org/download/) [](https://npmjs.org/package/whistle) [](https://www.npmjs.com/package/whistle) [](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 ================================================ # whistle [](https://npmjs.org/package/whistle) [](http://nodejs.org/download/) [](https://npmjs.org/package/whistle) [](https://www.npmjs.com/package/whistle) [](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 ================================================' + util.encodeHtml(util.getErrorStack(err)) + '' : 'Internal Server Error'); } exports.sendError = sendError; exports.sendGzip = util.sendGzip; exports.sendGzipText = util.sendGzipText; ================================================ FILE: biz/webui/cgi-bin/values/add.js ================================================ var values = require('../../../../lib/rules/util').values; var recycleBin = require('../../../../lib/rules/util').values.recycleBin; var isGroup = require('../../../../lib/util/common').isGroup; module.exports = function(req, res) { var body = req.body; var list; var exists = values.exists(body.name); if (values.add(body.name, body.value, body.clientId) != null) { if (isGroup(body.name)) { if (body.focusName) { values.moveTo(body.name, body.focusName, body.clientId); } } else if (body.groupName) { values.moveToGroup(body.name, body.groupName); } else if (!exists) { var group = values.getFirstGroup(); group && values.moveTo(body.name, group.name, body.clientId, null, true); } } if (req.body.recycleFilename) { recycleBin.remove(req.body.recycleFilename); list = recycleBin.list(); } res.json({ ec: 0, list: list }); }; ================================================ FILE: biz/webui/cgi-bin/values/export.js ================================================ var values = require('../../../../lib/rules/util').values; var util = require('../util'); module.exports = function(req, res) { var exportValues = req.query.values; try { exportValues = exportValues && JSON.parse(exportValues); } catch(e) { exportValues = null; } var result = {}; var list = []; values.list().forEach(function(file) { if (!exportValues || exportValues[file.name]) { result[file.name] = file.data; list.push(file.name); } }); result[''] = list; var filename = req.query.filename; if (filename && typeof filename === 'string') { if (!/\.(txt|json)/i.test(filename)) { filename += '.txt'; } } else { filename = 'values_' + util.formatDate() + '.txt'; } res.attachment(filename).send(JSON.stringify(result, null, ' ')); }; ================================================ FILE: biz/webui/cgi-bin/values/get.js ================================================ var values = require('../../../../lib/rules/util').values; var properties = require('../../../../lib/rules/util').properties; module.exports = function(req, res) { res.json({ fontSize: properties.get('valuesFontSize'), theme: properties.get('valuesTheme'), showLineNumbers: properties.get('valuesShowLineNumbers'), values: values.list() }); }; ================================================ FILE: biz/webui/cgi-bin/values/import.js ================================================ var get = require('./index'); var util = require('../util'); var addValues = require('../../../../lib/rules/util').addValues; module.exports = function(req, res) { util.getReqData(req, function(err, result) { if (err) { res.status(200).json({ ec: 2, em: err.message }); } else { addValues(result.data, result.replace, req.query.clientId); util.sendGzip(req, res, get()); } }); }; ================================================ FILE: biz/webui/cgi-bin/values/index.js ================================================ var rulesUtil = require('../../../../lib/rules/util'); var values = rulesUtil.values; module.exports = function get() { return { ec: 0, list: values.list() }; }; ================================================ FILE: biz/webui/cgi-bin/values/list.js ================================================ var get = require('./index'); var util = require('../util'); module.exports = function(req, res) { util.sendGzip(req, res, get()); }; ================================================ FILE: biz/webui/cgi-bin/values/list2.js ================================================ var get = require('./index'); module.exports = function(req, res) { var data; if (req.query.order) { data = []; get().list.forEach(function(item) { data.push({ name: item.name, value: item.data }); }); } else { var list = []; data = {}; get().list.forEach(function(item) { data[item.name] = item.data; list.push(item.name); }); data[''] = list; } res.json(data); }; ================================================ FILE: biz/webui/cgi-bin/values/move-to.js ================================================ var values = require('../../../../lib/rules/util').values; module.exports = function(req, res) { var body = req.body; var result = values.moveTo(body.from, body.to, body.clientId, body.group === 'true'); res.json({ec: result ? 0 : 2, em: 'success'}); }; ================================================ FILE: biz/webui/cgi-bin/values/recycle/list.js ================================================ var recycleBin = require('../../../../../lib/rules/util').values.recycleBin; var util = require('../../util'); module.exports = function(req, res) { util.sendGzip(req, res, { ec: 0, list: recycleBin.list() }); }; ================================================ FILE: biz/webui/cgi-bin/values/recycle/remove.js ================================================ var recycleBin = require('../../../../../lib/rules/util').values.recycleBin; module.exports = function(req, res) { recycleBin.remove(req.body.name); res.json({ ec: 0, list: recycleBin.list() }); }; ================================================ FILE: biz/webui/cgi-bin/values/recycle/view.js ================================================ var recycleBin = require('../../../../../lib/rules/util').values.recycleBin; module.exports = function(req, res) { var item = recycleBin.getFile(req.query.name); res.json({ ec: item ? 0 : 3, data: item && item.data }); }; ================================================ FILE: biz/webui/cgi-bin/values/remove.js ================================================ var util = require('../../../../lib/rules/util'); module.exports = function(req, res) { util.removeBatch(util.values, req.body); res.json({ec: 0, em: 'success'}); }; ================================================ FILE: biz/webui/cgi-bin/values/rename.js ================================================ var values = require('../../../../lib/rules/util').values; module.exports = function(req, res) { var body = req.body; values.rename(body.name, body.newName, body.clientId); res.json({ec: 0, em: 'success'}); }; ================================================ FILE: biz/webui/cgi-bin/values/value.js ================================================ var values = require('../../../../lib/rules/util').values; module.exports = function(req, res) { res.json({ value: values.get(req.query.key) }); }; ================================================ FILE: biz/webui/htdocs/editor.html ================================================
Warning: Unsaved changes will be lost
'),void o.html(e)):void(this.reloadTimer=setTimeout(this.reloadDataQuite,1e3))},showTab:function(){var e=c(this.state);e&&-1==e.indexOf("rules")?-1!=e.indexOf("values")?this.showValues():-1!=e.indexOf("plugins")?this.showPlugins():this.showNetwork():this.showRules(),F.set("pageName",e||"")},switchTab:function(e){var t=this,n=t.state.name,r=[];t.hideNetwork||r.push("network"),t.hideRules||r.push("rules"),t.hideValues||r.push("values"),t.hidePlugins||r.push("plugins");var o=r.indexOf(n),i=r.length;switch(e?(o-=1,0>o&&(o=i-1)):(o+=1,o>=i&&(o=0)),r[o]){case"network":t.showNetwork();break;case"rules":t.showRules();break;case"values":t.showValues();break;case"plugins":t.showPlugins()}},componentDidMount:function(){function e(e){if(e=e&&e.trim()){var t=e.indexOf("://")+3;if(e=-1!=t?e.substring(t):e,0===e.indexOf("{"))return t=e.lastIndexOf("}"),t>1?e.substring(1,t):null}}var t=this,n=new C(".w-copy-text");n.on("error",function(e){ee.alert("Copy failed")}),n=new C(".w-copy-text-with-tips"),n.on("error",function(e){G.error("Copy failed")}),n.on("success",function(e){G.success("Copied clipboard")});var r=function(e){e.preventDefault()};if(H.on("showRulesDialog",function(e,n){n&&!t.isHideRules()&&t.refs.rulesDialog.show(n.rules,n.values)}),H.on("changeRecordState",function(e,n){t.setState({record:n},t.updateList)}),H.on("showHttpsSettingsDialog",t.showHttpsSettingsDialog),Ce){var s=function(e,t){return H.editorMatchedCount=0,H.trigger(t?"findEditorPrev":"findEditorNext",e),H.editorMatchedCount};window.__findWhistleCodeMirrorEditor_=s}var c,u;H.one("networkDidMount",function(){u&&H.trigger("showComposerTab")}),H.one("composerDidMount",function(){c=!0,u&&(H.trigger("_setComposerData",u),u=null)}),H.on("showPluginOptionTab",function(e,n){n&&t.showPluginTab(Q.getSimplePluginName(n))}),H.on("disablePlugin",function(e,n,r){t.setPluginState(Q.getSimplePluginName(n),r)}),H.on("setComposerData",function(e,n){n&&!t.state.rulesMode&&ee.confirm("Do you confirm the changes to the composer's data?",function(e){e&&(c?H.trigger("_setComposerData",n):u=n)})}),H.on("showPluginOption",function(e,n){if(n){var r=Q.getSimplePluginName(n),o=n.pluginHomepage||"plugin."+r+"/";if((n.pluginHomepage||n.openExternal)&&!n.openInPlugins&&!n.openInModal)return window.open(o);var i=n.openInModal||"";i&&!n.pluginHomepage&&(o+="?openInModal=5b6af7b9884e1165"),t.refs.iframeDialog.show({favicon:Q.getPluginIcon(n),name:r,url:o,homepage:n.homepage,disabled:Q.pluginIsDisabled(t.state,r),width:i.width,height:i.height})}}),H.on("hidePluginOption",function(){t.refs.iframeDialog.hide()}),H.on("download",function(e,n){t.download(n)}),H.on("showMockDialog",function(e,n){n&&t.refs.mockDialog.show(n.item,n.type)}),H.on("enableRecord",function(){t.enableRecord()}),H.on("showJsonViewDialog",function(e,n,r){t.refs.jsonDialog.show(n,r)}),H.on("rulesChanged",function(e,n){t.rulesChanged=!0,t.showReloadRules(n===!0)}),H.on("switchTreeView",function(){t.toggleTreeView()}),H.on("updateGlobal",function(){t.setState({})}),H.on("valuesChanged",function(e,n){t.valuesChanged=!0,t.showReloadValues(n===!0)}),H.on("showNetwork",function(){t.showNetwork()}),H.on("showRules",function(e,n){t.showRules(),n&&t.state.rules.exists(n)&&(H.trigger("expandRulesGroup",n),t.setRulesActive(n))}),H.on("showValues",function(){t.showValues()}),H.on("showPlugins",function(e,n){n&&"string"==typeof n&&(t.setState({active:"Home"}),setTimeout(function(){H.trigger("highlightPlugin",n)},600)),t.showPlugins()}),H.on("disableAllPlugins",t.disableAllPlugins),H.on("disableAllRules",t.disableAllRules),H.on("activeRules",function(){var e=z.rulesModal;e.exists(z.activeRulesName)&&(t.setRulesActive(z.activeRulesName,e),t.setState({}))}),H.on("activeValues",function(){var e=z.valuesModal;e.exists(z.activeValuesName)&&(t.setValuesActive(z.activeValuesName,e),t.setState({}))});var p;H.on("openEditor",function(e,n){if("1"===F.get("viewAllInNewWindow"))return Q.openInNewWin(n||"");try{if(p&&"function"==typeof p.setValue)return window.getTextFromWhistle_=null,t.refs.editorWin.show(),p.setValue(n);window._initWhistleTextEditor_=function(e){p=e,p.setValue(n)},t.refs.editorWin.show("editor.html")}catch(r){}}),H.on("openInNewWin",function(){try{Q.openInNewWin(p.getEditorValue()||""),t.refs.editorWin.hide()}catch(e){}});var h;H.on("updateUIThrottle",function(){h||(h=setTimeout(function(){h=null,t.setState({})},200))}),H.on("addNewRulesFile",function(e,n){var r=n.filename,o=t.state.rules,i=o.add(r,n.data);o.setChanged(r,!1),t.setRulesActive(r),t.setState({activeRules:i}),n.update||t.triggerRulesChange("create")}),H.on("addNewValuesFile",function(e,n){var r=n.filename,o=t.state.values,i=o.add(r,n.data);o.setChanged(r,!1),n.update?t.setState({}):(t.setValuesActive(r),t.setState({activeValues:i}),t.triggerValuesChange("create"))}),H.on("recoverRules",function(e,n){var r=t.state.rules,o=n.filename,i=function(e){e&&z.rules.add({name:o,value:n.data,recycleFilename:n.name},function(e,i){if(e&&0===e.ec){var a=r.add(o,n.data);t.setRulesActive(o),t.setState({activeRules:a}),t.triggerRulesChange("create"),H.trigger("rulesRecycleList",e),H.trigger("focusRulesList")}else Q.showSystemError(i)})};return r.exists(o)?void ee.confirm("The name '"+o+"' is already in use. Overwrite?",i):i(!0)}),H.on("recoverValues",function(e,n){var r=t.state.values,o=n.filename,i=function(e){e&&z.values.add({name:o,value:n.data,recycleFilename:n.name},function(e,i){if(e&&0===e.ec){var a=r.add(o,n.data);t.setValuesActive(o),t.setState({activeValues:a}),t.triggerValuesChange("create"),H.trigger("valuesRecycleList",e)}else Q.showSystemError(i)})};return r.exists(o)?void ee.confirm("The name '"+o+"' is already in use. Overwrite?",i):i(!0)}),H.on("networkImportFile",function(e,n){t.uploadSessionsForm(n)}),H.on("networkImportData",function(e,n){t.importAnySessions(n)}),H.on("rulesImportFile",function(e,n){l(n,t.handleImportRules)}),H.on("rulesImportData",function(e,n){t.handleImportRules(n)}),H.on("valuesImportFile",function(e,n){l(n,t.handleImportValues)}),H.on("valuesImportData",function(e,n){t.handleImportValues(n)}),H.on("networkSettingsImportFile composerImportFile rulesSettingsImportFile valuesSettingsImportFile",function(e,t){l(t,Q.noop,e.type)}),H.on("networkSettingsImportData composerImportData rulesSettingsImportFile valuesSettingsImportFile",function(e,t){Q.handleImportData(t)}),H.on("setRulesSettings",function(e,n){n&&ee.confirm("Do you confirm the changes to the rules settings?",function(e){e&&(t.setState({rulesTheme:n.theme,rulesFontSize:n.fontSize,showRulesLineNumbers:n.lineNumbers,autoRulesLineWrapping:n.autoLineWrapping}),F.set("rulesTheme",o(n.theme).substring(0,30)),F.set("rulesFontSize",o(n.fontSize).substring(0,30)),F.set("showRulesLineNumbers",!!n.lineNumbers),F.set("autoRulesLineWrapping",n.autoLineWrapping?"1":""),t.setMultipleCohice(n.allowMultipleChoice),t.setBackRulesFirst(n.backRulesFirst))})}),H.on("setValuesSettings",function(e,n){n&&ee.confirm("Do you confirm the changes to the values settings?",function(e){e&&(t.setState({valuesTheme:n.theme,valuesFontSize:n.fontSize,showValuesLineNumbers:n.lineNumbers,autoValuesLineWrapping:n.autoLineWrapping,foldGutter:n.foldGutter}),F.set("valuesTheme",o(n.theme).substring(0,30)),F.set("valuesFontSize",o(n.fontSize).substring(0,10)),F.set("showValuesLineNumbers",!!n.lineNumbers),F.set("autoValuesLineWrapping",n.autoLineWrapping?"1":""),F.set("foldGutter",n.foldGutter?"1":""))})}),y(document).on("dragleave",r).on("dragenter",r).on("dragover",r).on("drop",function(e){e.preventDefault();var n=e.originalEvent.dataTransfer.files,r=n&&n[0];if(r){var o=e.target;"TEXTAREA"===o.nodeName&&(e.preventDefault(),o.readOnly=!0,setTimeout(function(){o.readOnly=!1},0)),o=y(o);var i=o.closest(".w-fix-drag").find("iframe")[0];if(i)try{var a=i.contentWindow;if(a&&"function"==typeof a.onWhistleFileDrop)return a.onWhistleFileDrop(r)}catch(e){console.error(e)}if(y(".w-show-upload-temp-file.in").length)return H.trigger("uploadTempFile",r);if(y(".w-import-dialog.in").length)return H.trigger("importFile",r);var s=t.state.name,c=r.name;if("network"===s){if(o.closest(".w-frames-com").length)return;return/\.log$/i.test(c)?r.size>fe?a.alert("Maximum file size: 2MB"):void Q.readFileAsText(r,function(e){e=Q.parseLogs(e),e&&(null!==z.uploadLogs&&(z.uploadLogs=e),H.trigger("showLog"),H.trigger("uploadLogs",{logs:e}))}):t.uploadSessionsForm(r)}l(r,function(e){e&&("rules"===s?t.handleImportRules(e):"values"===s&&t.handleImportValues(e))})}}).on("keyup",function(e){if((e.metaKey||e.ctrlKey)&&82===e.keyCode)!Ce&&e.preventDefault();else if(191===e.keyCode){var n=t.state.name,r=document.activeElement&&document.activeElement.nodeName;if("INPUT"!==r&&"TEXTAREA"!==r&&!y(".modal.in").length)if("network"===n){if(!Q.hasShortcut("focusNetworkSearchBox"))return;H.trigger("focusNetworkFilterInput")}else if("rules"===n){if(!Q.hasShortcut("focusRulesSearchBox"))return;H.trigger("focusRulesFilterInput")}else if("values"===n){if(!Q.hasShortcut("focusValuesSearchBox"))return;H.trigger("focusValuesFilterInput")}}}).on("contextmenu",".w-textarea-bar",function(e){e.preventDefault()});var g=function(e){var n=e.target;"A"==n.nodeName&&y(n).parent().hasClass("w-list-data")&&("rules"==t.state.name?t.removeRules():t.removeValues()),e.preventDefault()};y(window).on("hashchange",t.showTab).on("keyup",function(e){if(27==e.keyCode){t.setMenuOptionsState();var n=y(".modal");"function"==typeof n.modal&&n.modal("hide")}}).on("keydown",function(e){var n=t.state.name,r=e.keyCode;if(46==r&&g(e),!e.ctrlKey&&!e.metaKey)return void(112===r?(e.preventDefault(),window.open(Q.getDocUrl("gui/"+n+".html"))):116===r&&e.preventDefault());var o=37===r;if(o||39===r){if(!Q.hasShortcut(o?"switchTabReverse":"switchTab"))return;return t.switchTab(o),e.preventDefault()}if(79===r){if("network"===n){if(!Q.hasShortcut("toggleNetworkState"))return;H.trigger("toggleNetworkState")}else if("rules"===n){if(!Q.hasShortcut("toggleRules"))return;t.confirmDisableAllRules()}else if("plugins"===n){if(!Q.hasShortcut("togglePlugins"))return;t.confirmDisableAllPlugins()}e.preventDefault()}else if(76===r){if("network"===n){if(!Q.hasShortcut("toggleNetworkPanelLayout"))return;H.trigger("toggleNetworkDock")}else if("rules"===n){if(!Q.hasShortcut("toggleRulesNum"))return;H.trigger("toggleRulesLineNumbers")}else if("values"===n){if(!Q.hasShortcut("toggleValuesNum"))return;H.trigger("toggleValuesLineNumbers")}e.preventDefault()}else if(82===r)!Ce&&e.preventDefault();else if(77===r)t.toggleLeftMenu(),e.preventDefault();else if(66===r){if(!Q.hasShortcut("switchNetworkView"))return;return t.toggleTreeView(),e.preventDefault(),void H.trigger("toggleTreeViewByAccessKey")}var i="network"===n;if(i&&88==r)return void(Q.isFocusEditor()||y(e.target).closest(".w-frames-list").length||!Q.hasShortcut("clearNetworkSessions")||t.clear());if(68==r){if(!Q.hasShortcut(i?"removeNetworkSessions":"rules"===n?"removeRules":"removeValues"))return;return g(e)}var a=t.state.network;if(i&&(83===r||69===r)){if(83===r){if(!Q.hasShortcut("saveNetwork"))return;return e.preventDefault(),void(Q.noModal()&&H.trigger("saveSessions"))}if(e.preventDefault(),!Q.noModal())return void(y(Se(t.refs.chooseFileType)).is(":visible")&&t.exportBySave());var s=e.target.nodeName;if("INPUT"===s||"TEXTAREA"===s)return;var l=a.hasSelected();return void(l&&(y(Se(t.refs.chooseFileType)).modal("show"),setTimeout(function(){var e=Se(t.refs.sessionsName);e.focus(),e.select()},500)))}if(69===r){if(!Q.hasShortcut(i?"exportNetwork":"rules"===n?"exportRules":"exportValues"))return;return e.preventDefault(),Q.noModal()&&t.exportData()}if(190===r){if(!Q.hasShortcut(i?"openNetworkSettings":"rules"===n?"openRulesSettings":"openValuesSettings"))return;return t.showSettings(),e.preventDefault()}var c=74===r;if(c||73===r){if(Q.noModal())if(c){if(!z.whistleId||!Q.hasShortcut("openService"))return;t.showService()}else if(i||"rules"===n||"values"===n){if(!Q.hasShortcut(i?"importNetwork":"rules"===n?"importRules":"importValues"))return;t.importData()}else if("plugins"===n){if(!Q.hasShortcut("openInstallPlugins"))return;H.trigger("installPlugins")}e.preventDefault()}});var f=function(){var e=t.state.name;return"rules"===e||"values"===e};y(document.body).on("mouseenter",Ae,function(t){if(f()&&(t.ctrlKey||t.metaKey)){var n,r=y(this);(r.hasClass("cm-js-http-url")||r.hasClass("cm-string")||r.hasClass("cm-js-at")||ce.test(n=r.text())||i(n)||e(n))&&r.addClass("w-is-link")}}).on("mouseleave",Ae,function(e){y(this).removeClass("w-is-link")}).on("mousedown",Ae,function(n){if(f()&&(n.ctrlKey||n.metaKey)){var r=y(this),o=r.text();if(r.hasClass("cm-js-at"))return void(we.test(o)&&window.open((RegExp.$1||"http:")+RegExp.$2));if(r.hasClass("cm-string"))return void(Me.test(o)&&window.open((RegExp.$1||"http:")+RegExp.$2));if(r.hasClass("cm-js-http-url"))return/^https?:\/\//i.test(o)||(o="http:"+("/"===o[0]?"":"//")+o),void window.open(o);if(ce.test(o)||i(o)&&ue.test(o)){var a=RegExp.$1;return H.trigger("showEditorDialog",[{ruleName:t.getActiveRuleName(),tempFile:a},r])}var s=e(o);if(s){var l=t.state.rules.getActive(),c=l&&l.value,u={};return Q.resolveInlineValues(c,u),null==u[s]?H.trigger("showEditorDialog",{name:s}):ee.confirm("The value of '"+s+"' is stored in this rule file and cannot be synced if edited via the Values's editor. Continue?",function(e){e&&H.trigger("showEditorDialog",{name:s})})}}}),"network"==t.state.name&&t.startLoadData(!0),z.on("settings",function(e){var n=t.state,r=e.server,o=n.whistleId!==r.whistleId;o&&(n.whistleId=r.whistleId);var i=[],a=Q.getCAHash(r,i);if(a!==n.caHash&&(n.caHash=a,n.caUrlList=i,o=!0),n.interceptHttpsConnects!==e.interceptHttpsConnects||n.enableHttp2!==e.enableHttp2||n.disabledAllRules!==e.disabledAllRules||n.allowMultipleChoice!==e.allowMultipleChoice||n.disabledAllPlugins!==e.disabledAllPlugins||n.backRulesFirst!==e.backRulesFirst||n.ndp!=r.ndp||n.ndr!=r.ndr||n.drb!=r.drb||n.drm!=r.drm||n.port!=r.port){n.interceptHttpsConnects=e.interceptHttpsConnects,n.enableHttp2=e.enableHttp2,n.disabledAllRules=e.disabledAllRules,n.allowMultipleChoice=e.allowMultipleChoice,n.backRulesFirst=e.backRulesFirst,n.disabledAllPlugins=e.disabledAllPlugins,n.ndp=r.ndp,n.ndr=r.ndr,n.drb=r.drb,n.drm=r.drm,n.port=r.port,O.setPlugins(n);var s=ke;return s[3].checked=!n.disabledAllRules,s[4].checked=!n.disabledAllPlugins,t.refs.contextMenu.update(),t.setState({})}o&&t.setState({})}),z.on("rules",function(e){var n=t.state.rules,r=e.list;e.defaultRulesIsDisabled||-1!==r.indexOf("Default")||r.unshift("Default");var o=n.getSelectedNames();d(o,r)||(t.reselectRules(e,!0),t.setState({}))}),z.on("serverInfo",function(e){t.serverInfo=e}),H.on("autoRefreshNetwork",function(){!t.state.network.isTreeView&&t.autoRefresh&&t.autoRefresh()});var m=function(e){if(Array.isArray(e))return e;if(e&&!e.selected)return[e]};H.on("updateUI",function(){t.setState({})}),H.on("replaySessions",function(e,n,r){var o=t.state.network,i=m(n)||o.getSelectedList(),a=i&&i.length;return r&&1===a?(t.replayList=i,t.refs.setReplayCount.show(),void setTimeout(function(){var e=Se(t.refs.replayCount);e.select(),e.focus()},300)):void t.replay(e,i)}),H.on("filterSessions",t.showSettings),H.on("exportSessions",function(e,n,r){t.exportData(e,m(n),r)}),H.on("abortRequest",function(e,n){t.abort(m(n))}),H.on("removeIt",function(e,n){var r=t.state.network;n&&r&&(r.remove(n),t.setState({}))}),H.on("removeOthers",function(e,n){var r=t.state.network;n&&r&&(n.selected?r.removeUnselectedItems():r.removeOthers(n),t.setState({}))}),H.on("clearAll",t.clear),H.on("removeSelected",function(){var e=t.state.network;e&&(e.removeSelectedItems(),t.setState({}))}),H.on("removeUnselected",function(){var e=t.state.network;e&&(e.removeUnselectedItems(),t.setState({}))}),H.on("removeUnmarked",function(){var e=t.state.network;e&&(e.removeUnmarkedItems(),t.setState({}))}),H.on("saveRules",function(e,n){if(n.changed||!n.selected){var r=t.state.rules.getChangedGroupList(n);r.forEach(t.selectRules)}else t.unselectRules(n)}),H.on("saveValues",function(e,n){var r=t.state.values.getChangedGroupList(n);r.forEach(t.saveValues)}),H.on("renameRules",function(e,n){t.showEditRules(n)}),H.on("renameValues",function(e,n){t.showEditValues(n)}),H.on("deleteRules",function(e,n){setTimeout(function(){t.removeRules(n)},0)}),H.on("deleteValues",function(e,n){setTimeout(function(){t.removeValues(n)},0)}),H.on("createRules",t.showCreateRules),H.on("createValues",t.showCreateValues),H.on("showImportDialog",function(e,n){t.refs.importDialog.show(n||t.state.name)}),H.on("showExportDialog",function(e,n,r){t.refs.exportDialog.show(n||t.state.name,r)}),H.on("exportData",t.exportData),H.on("handleImportRules",function(e,n){t.handleImportRules(n)}),H.on("handleImportValues",function(e,n){t.handleImportValues(n)}),H.on("uploadRules",function(e,n){var r=a(n);r.append("replaceAll","1"),z.upload.importRules(r,function(e,n){e?0===e.ec?(t.reloadRules(e),G.success("Rules imported successfully")):ee.alert(e.em):Q.showSystemError(n)})}),H.on("uploadValues",function(e,n){var r=a(n,"values");r.append("replaceAll","1"),z.upload.importValues(r,function(e,n){e||Q.showSystemError(n),0===e.ec?(t.reloadValues(e),G.success("Values imported successfully")):ee.alert(e.em)})});var A,M,w=document.hidden;y(document).on("visibilitychange",function(){clearTimeout(A);var e="network"===t.state.name;return document.hidden||!e?void(e&&w!==document.hidden&&(w=!0,M=t.scrollerAtBottom&&t.scrollerAtBottom())):(w=!1,void(A=setTimeout(function(){var e=M||t.scrollerAtBottom&&t.scrollerAtBottom();M=!1,t.setState({},function(){e&&t.autoRefresh()})},100)))}),setTimeout(function(){z.checkUpdate(function(e){e&&e.showUpdate&&t.setState({version:e.version,latestVersion:e.latestVersion},function(){y(Se(t.refs.showUpdateTipsDialog)).modal("show")})})},1e4),z.getLogIdList=this.getLogIdListFromRules,z.importAnySessions=t.importAnySessions,z.on("plugins",function(e){var n=t.createPluginsOptions(e.plugins),r=t.state.pluginsOptions,o=t.state.disabledPlugins,i=t.state.disabledAllPlugins,a=e.disabledPlugins;if(i==e.disabledAllPlugins&&n.length==r.length){for(var s,l=0,c=n.length;c>l;l++){var u=n[l],d=r[l];if(u.name!=d.name||u.latest!==d.latest||u.mtime!=d.mtime||o[u.name]!=a[u.name]||u.hideLongProtocol!=d.hideLongProtocol||u.hideShortProtocol!=d.hideShortProtocol||u.path!=d.path){s=!0;break}}if(!s)return}var p=t.state.plugins;p&&e.plugins&&Object.keys(e.plugins).forEach(function(t){var n=p[t];if(n){var r=e.plugins[t];r.selectedRulesHistory=n.selectedRulesHistory,r.selectedValuesHistory=n.selectedValuesHistory}});var h={plugins:e.plugins,disabledPlugins:e.disabledPlugins,pluginsOptions:n,disabledAllPlugins:e.disabledAllPlugins};O.setPlugins(h),t.setState(h)});try{var v=window.parent.onWhistleReady;if("function"==typeof v){var x=function(e){var n=e&&t.state.network,r=n&&n.getList().indexOf(e);r>=0&&H.trigger("selectedIndex",r)},T=function(e){H.trigger("selectedIndex",e)};v({url:location.href,pageId:z.getPageId(),compose:z.compose,createComposeInterrupt:z.createComposeInterrupt,importSessions:t.importAnySessions,importHarSessions:t.importHarSessions,clearSessions:t.clear,selectIndex:T,selectItem:x,setActive:function(e){e>=0?T(e):x(e)}})}}catch(N){}t.handleDataUrl(b||Q.getDataUrl()),z.handleDataUrl=t.handleDataUrl,b=null;var I,E,D,S,L=6e3,k=function j(){if(!z.whistleId)return I=E=D=null,setTimeout(j,L);S!==z.whistleId&&(I=E=D=null,S=z.whistleId);var e,n=JSON.stringify(t.refs.networkSettings.getSettings()),r=JSON.stringify(t.getRulesSettings()),o=JSON.stringify(t.getValuesSettings());return I!==n&&(e={networkSettings:n}),E!==r&&(e=e||{},e.rulesSettings=r), D!==o&&(e=e||{},e.valuesSettings=o),e?(e.type="settings",void z.saveToService(e,function(e){setTimeout(j,L),e&&0===e.ec&&(D=o,E=r,I=n)})):setTimeout(j,L)};setTimeout(k,L)},shouldComponentUpdate:function(e,t){var n=this.state.name;return"network"===n&&t.name!==n&&(this._isAtBottom=this.scrollerAtBottom&&this.scrollerAtBottom()),!0},handleDataUrl:function(e){if(e=o(e)){var t=this;z.getRemoteData(e,function(e,n){e||t.importAnySessions(n)})}},importAnySessions:function(e){if(e&&!Q.handleImportData(e)){var t=Array.isArray(e);t||Array.isArray(e.log&&e.log.entries)||(t=!0,e=[e]),Array.isArray(e)?z.addNetworkList(e):this.importHarSessions(e)}},donotShowAgain:function(){z.donotShowAgain()},hideUpdateTipsDialog:function(){y(Se(this.refs.showUpdateTipsDialog)).modal("hide")},getAllRulesText:function(){var e=" "+this.getAllRulesValue();return e.replace(/#[^\r\n]*[\r\n]/g,"\n")},getLogIdListFromRules:function(){var e=this.getAllRulesText();if(e=e.match(/\slog:\/\/(?:\{[^\s]{1,36}\}|[^/\\{}()<>\s]{1,36})\s/g)){var t={};e=e.map(function(e){return e=Q.removeProtocol(e.trim()),"{"===e[0]&&(e=e.slice(1,-1)),e}).filter(function(e){return e?t[e]?!1:(t[e]=1,!0):!1})}return e},getWeinreFromRules:function(){var e=this.state.values,t=this.getAllRulesText();if(t=t.match(/(?:^|\s)weinre:\/\/[^\s#]+(?:$|\s)/gm)){var n={};t=t.map(function(t){t=Q.removeProtocol(t.trim());var n=h(t);if(n!==!1)return n;var r=p(t);return r!==!1?(r=e.get(r),r&&r.value):t}).filter(function(e){return e?n[e]?!1:(n[e]=1,!0):!1})}return t},getValuesFromRules:function(){var e=" "+this.getAllRulesValue();return(e=e.match(/\s(?:[\w-]+:\/\/)?\{[^\s#]+\}/g))&&(e=e.map(function(e){return p(Q.removeProtocol(e.trim()))}).filter(function(e){return!!e})),e},getAllRulesValue:function(){var e=[],t=[],n=[],r=this.state.rules;return r.list.forEach(function(o){var i=r.get(o),a=i.value||"";i.active?t.push(a):i.selected?n.push(a):e.push(a)}),r=this.state.values,r.list.forEach(function(t){/\.rules$/.test(t)&&e.push(r.get(t).value)}),t.concat(n).concat(e).join("\r\n")},preventBlur:function(e){"INPUT"!=e.target.nodeName&&e.preventDefault()},startLoadData:function(e){function t(e,i){e=e||o.state.network,clearTimeout(a),a=null,"network"==o.state.name&&(i=i||r(),e.update(i)&&i&&(a=setTimeout(t,3e3)),document.hidden||o.setState({},function(){i&&n()}))}function n(e){(e||!o.state.network.isTreeView)&&(l.scrollTop=1e7)}function r(e){var t=s.find(".ReactVirtualized__Grid__innerScrollContainer")[0];if(!t)return e&&H.trigger("toggleBackToBottomBtn",!1),!0;var n=l.offsetHeight+5,r=t.offsetHeight,o=l.scrollTop+n>r;return H.trigger("toggleBackToBottomBtn",!o&&r>=n),o}var o=this;if(o._updateNetwork)return void(e?o._updateNetwork():setTimeout(o._updateNetwork,30));var i,a,s=y(".w-req-data-list .ReactVirtualized__Grid:first").scroll(function(){var e=o.state.network;i&&clearTimeout(i),i=null,r()&&(i=setTimeout(function(){t(e,!0)},1e3))}),l=s[0];this.container=s,z.on("data",t),y(document).on("dblclick",".w-network-menu-list",function(e){y(e.target).hasClass("w-network-menu-list")&&(l.scrollTop<1?n(!0):l.scrollTop=0)}),o._updateNetwork=t,o.autoRefresh=n,o.scrollerAtBottom=r,H.on("checkAtBottom",r)},showPlugins:function(e){"plugins"!=this.state.name?(this.setMenuOptionsState(),this.hidePluginsOptions()):e&&!this.state.showLeftMenu&&this.showPluginsOptions(),this.setState({hasPlugins:!0,name:"plugins"}),Q.changePageName("plugins")},handleAction:function(e){if("top"===e)return void(this.container[0].scrollTop=0);if("bottom"===e)return this.autoRefresh(!0);if("pause"===e)return H.trigger("changeRecordState",e),z.pauseNetworkRecord();var t="refresh"===e;return t?H.trigger("changeRecordState"):H.trigger("changeRecordState","stop"),z.stopNetworkRecord(!t),t?this.autoRefresh():void 0},showNetwork:function(e){var t=this;return"network"==t.state.name?void(e&&!t.state.showLeftMenu&&t.showNetworkOptions()):(t.setMenuOptionsState(),t.setState({hasNetwork:!0,name:"network"},function(){t.startLoadData(),t._isAtBottom&&(t._isAtBottom=!1,t.autoRefresh&&t.autoRefresh())}),void Q.changePageName("network"))},handleNetwork:function(e,t){var n=this.state.network;"removeAll"==e.id?this.clear():"removeSelected"==e.id?n.removeSelectedItems():"removeUnselected"==e.id?n.removeUnselectedItems():"exportWhistleFile"==e.id?this.exportData():"toggleView"===e.id?this.toggleTreeView():"importSessions"===e.id&&this.importData(),this.hideNetworkOptions()},importData:function(){this.refs.importDialog.show(this.state.name)},getRulesSettings:function(){var e=this.state;return{type:"setRulesSettings",theme:e.rulesTheme||"cobalt",fontSize:e.rulesFontSize||"14px",lineNumbers:!!e.showRulesLineNumbers,autoLineWrapping:!!e.autoRulesLineWrapping,allowMultipleChoice:!!e.allowMultipleChoice,backRulesFirst:!!e.backRulesFirst}},getValuesSettings:function(){var e=this.state;return{type:"setValuesSettings",theme:e.valuesTheme||"cobalt",fontSize:e.rulesFontSize||"14px",lineNumbers:!!e.showValuesLineNumbers,autoLineWrapping:!!e.autoValuesLineWrapping,foldGutter:!!e.foldGutter}},importRulesSettings:function(){this.refs.importDialog.show("rulesSettings")},exportRulesSettings:function(){this.refs.exportDialog.show("rulesSettings",this.getRulesSettings())},importValuesSettings:function(){this.refs.importDialog.show("valuesSettings")},exportValuesSettings:function(){this.refs.exportDialog.show("valuesSettings",this.getValuesSettings())},getInputValue:function(){return Q.formatFilename(Se(this.refs.sessionsName).value.trim())},filterFilename:function(e){this.setState({filename:Q.formatFilename(e.target.value)})},exportData:function(e,t,n){switch(this.state.name){case"network":var r=this.state.network,o=Array.isArray(t)||r.hasSelected();if(this.currentFoucsItem=t,o){y(Se(this.refs.chooseFileType)).modal("show");var i=Se(this.refs.sessionsName);n&&"string"==typeof n&&(i.value=n),setTimeout(function(){i.focus(),i.select()},500)}else G.info("Please select one or more sessions first");break;case"rules":this.showAndActiveRules({id:"exportRules"});break;case"values":this.showAndActiveValues({id:"exportValues"})}},showService:function(){Q.showService(this.state.name)},importSessionsFromUrl:function(e){var t=this;e&&z.getRemoteData(e,function(e,n){e||t.importAnySessions(n)})},handleImportRules:function(e){e&&!Q.handleImportData(e)&&this.showKVDialog(e)},handleImportValues:function(e){e&&!Q.handleImportData(e)&&this.showKVDialog(e,!0)},showAndActiveRules:function(e,t){if("rules"===this.state.name)switch(e.id){case"exportRules":this.refs.selectRulesDialog.show();break;case"importRules":this.importData()}else this.setRulesActive(e.name),this.showRules();this.hideRulesOptions()},showRules:function(e){"rules"!=this.state.name?(this.setMenuOptionsState(),this.hideRulesOptions()):e&&!this.state.showLeftMenu&&this.showRulesOptions(e),this.setState({hasRules:!0,name:"rules"}),Q.changePageName("rules")},showAndActiveValues:function(e,t){var n=this;if("values"===n.state.name&&e.id)switch(e.id){case"exportValues":n.refs.selectValuesDialog.show();break;case"importValues":this.importData()}else{var r=n.state.values,o=e.name;r.exists(o)?n.setValuesActive(o):z.values.add({name:o},function(e,t){if(e&&0===e.ec){var i=r.add(o);n.setValuesActive(o),n.setState({activeValues:i}),H.trigger("focusValuesList")}else Q.showSystemError(t)}),this.showValues()}n.hideValuesOptions()},addValue:function(){},showValues:function(e){"values"!=this.state.name?(this.setMenuOptionsState(),this.hideValuesOptions()):e&&!this.state.showLeftMenu&&this.showValuesOptions(e),this.setState({hasValues:!0,name:"values"}),Q.changePageName("values")},showNetworkOptions:function(){"network"==this.state.name&&this.setState({showNetworkOptions:!0})},hideNetworkOptions:function(){this.setState({showAbortOptions:!1,showNetworkOptions:!1})},showAbortOptions:function(){var e=this.state.network,t=e.getSelectedList();Be[0].disabled=!t||!t.filter(Q.canAbort).length,this.setState({showAbortOptions:!0})},showCreateOptions:function(){this.setState({showCreateOptions:!0})},hideCreateOptions:function(){this.setState({showCreateOptions:!1})},hideAbortOptions:function(){this.setState({showAbortOptions:!1})},showHelpOptions:function(){this.setState({showHelpOptions:!0})},hideHelpOptions:function(){this.setState({showHelpOptions:!1})},showHasNewVersion:function(e){this.setState({hasNewVersion:e})},showRulesOptions:function(e){var t,n=this,r=n.state.rules,o=r.data,i=r.list;if("rules"===n.state.name){var a=i.length;je[0].disabled=2>a,je[1].disabled=1>a,t=je}else t=[],i.forEach(function(e){t.push(o[e])});n.setState({rulesOptions:t,showRulesOptions:!0})},hideRulesOptions:function(){this.setState({showRulesOptions:!1})},showValuesOptions:function(e){var t,n=this,r=this.state.values.list;if("values"===n.state.name){var o=r.length;Ue[0].disabled=2>o,Ue[1].disabled=1>o,t=Ue}else{t=[];var i=n.getValuesFromRules()||[];i=Q.unique(r.concat(i));var a=[];i.forEach(function(e){var n=-1!=r.indexOf(e),o={name:e,icon:n?"edit":"plus"};n?t.push(o):a.push(o)}),t=a.concat(t)}n.setState({valuesOptions:t,showValuesOptions:!0})},hideValuesOptions:function(){this.setState({showValuesOptions:!1})},showAndActivePlugins:function(e){this.hidePluginsOptions(),this.showPlugins(),this.showPluginTab(e.name)},showPluginTab:function(e){var t="Home",n=this.state.tabs||[];if(e&&e!=t)for(var r=0,o=n.length;o>r;r++)if(n[r].name==e){t=e,e=null;break}var i=e&&this.state.plugins[e+":"];if(i){if(n.length>=pe)return ee.alert("Maximum "+pe+" tabs allowed"),this.showPlugins();if(t=e,i.pluginHomepage&&!i.openInPlugins)return window.open(i.pluginHomepage);n.push({name:e,url:i.pluginHomepage||"plugin."+e+"/"})}this.setState({active:t,tabs:n}),this.updatePluginTabInfo(n,t)},updatePluginTabInfo:function(e,t){e=e.map(function(e){return e.name}),F.set("activePluginTabList",JSON.stringify(e)),t&&F.set("activePluginTabName",t)},activePluginTab:function(e){this.showPluginTab(y(e.target).attr("data-name"))},closePluginTab:function(e){for(var t=y(e.target).attr("data-name"),n=this.state.tabs||[],r=0,o=n.length;o>r;r++)if(n[r].name==t){n.splice(r,1);var i=this.state.active;if(i==t){var a=n[r]||n[r-1];this.state.active=a?a.name:null}return this.setState({tabs:n}),void this.updatePluginTabInfo(n)}},showPluginsOptions:function(e){this.setState({showPluginsOptions:!0})},hidePluginsOptions:function(){this.setState({showPluginsOptions:!1})},showWeinreOptionsQuick:function(e){var t=this.getWeinreFromRules();return t&&t.length?(y(e.target).closest("div").addClass("w-menu-wrapper-show"),void Q.shakeElem(y(Se(this.refs.weinreMenuItem)))):void this.showAnonymousWeinre()},showWeinreOptions:function(e){var t=this,n=t.state.weinreOptions=t.getWeinreFromRules()||[];t.state.weinreOptions=Q.unique(n).map(function(e){return{name:e,icon:"console"}}),t.setState({showWeinreOptions:!0})},hideWeinreOptions:function(){this.setState({showWeinreOptions:!1})},setMenuOptionsState:function(e,t){var n={showCreateRules:!1,showCreateValues:!1,showEditRules:!1,showEditValues:!1,showCreateOptions:!1};e&&(n[e]=!0),this.setState(n,t)},hideRulesInput:function(){this.setState({showCreateRules:!1})},hideValuesInput:function(){this.setState({showCreateValues:!1})},hideRenameRuleInput:function(){this.setState({showEditRules:!1})},hideRenameValueInput:function(){this.setState({showEditValues:!1})},showCreateRules:function(e,t,n){var r=Se(this.refs.createRulesInput);this._curFocusRulesGroup=t,this._curFocusRulesItem=n,this.setState({showCreateRules:!0},function(){r.focus()})},showCreateValues:function(e,t,n){var r=Se(this.refs.createValuesInput);this._curFocusValuesGroup=t,this._curFocusValuesItem=n,this.setState({showCreateValues:!0},function(){r.focus()})},showHttpsSettingsDialog:function(){this.refs.httpsSettings.show()},interceptHttpsConnects:function(e){var t=this,n=e.target.checked;z.interceptHttpsConnects({interceptHttpsConnects:n?1:0},function(e,r){e&&0===e.ec?(t.state.interceptHttpsConnects=n,z.isCapture=n?1:0,H.trigger("reqTabsChange"),H.trigger("resTabsChange")):Q.showSystemError(r),t.setState({})})},enableHttp2:function(e){var t=this;if(!z.supportH2)return void ee.confirm("HTTP/2 requires Node.js LTS version v16+. Please upgrade",function(e){e&&window.open("https://nodejs.org/"),t.setState({})});var n=e.target.checked;z.enableHttp2({enableHttp2:n?1:0},function(e,r){e&&0===e.ec?t.state.enableHttp2=n:Q.showSystemError(r),t.setState({})})},createRules:function(e){if(13==e.keyCode||"click"==e.type){var t=this,n=Se(t.refs.createRulesInput),r=n.value.trim();if(!r)return void G.error("The name is required");var o,i=t.state.rules,a=e&&e.target.getAttribute("data-type");if("group"===a&&(o=!0,r="\r"+r),i.exists(r))return void G.error("The name '"+r+"' is already in use");var s="top"===a?1:"",l=t._curFocusRulesGroup,c=t._curFocusRulesItem,u={name:r,addToTop:s};if(o){var d=c&&c.name;d&&("Default"===d&&(d=t.state.rules.list[1]),u.focusName=d)}else l&&(u.groupName=l.name);z.rules.add(u,function(e,a){if(e&&0===e.ec){var l=i[s?"unshift":"add"](r);n.value="",n.blur();var c=u.focusName;c?i.moveTo(r,c):i.moveToGroup(r,u.groupName,s),o?l&&(l._isNewGroup=!0):t.setRulesActive(r),u.groupName&&H.trigger("expandRulesGroup",u.groupName),t.setState(o?{}:{activeRules:l}),t.triggerRulesChange("create")}else Q.showSystemError(a)})}},createValues:function(e){if(13==e.keyCode||"click"==e.type){var t=this,n=Se(t.refs.createValuesInput),r=n.value.trim();if(!r)return void G.error("The name is required");if(/\s/.test(r))return void G.error("Spaces are not allowed in the name");if(/#/.test(r))return void G.error("Special character '#' is not allowed in the name");var o,i=t.state.values,a=e&&e.target.getAttribute("data-type");if("group"===a&&(o=!0,r="\r"+r),i.exists(r))return void G.error("The name '"+r+"' is already in use");var s=t._curFocusValuesGroup,l=t._curFocusValuesItem,c={name:r};o?l&&(c.focusName=l.name):s&&(c.groupName=s.name),z.values.add(c,function(e,a){if(e&&0===e.ec){var s=i.add(r);n.value="",n.blur();var l=c.focusName;l?i.moveTo(r,l):i.moveToGroup(r,c.groupName),o?s&&(s._isNewGroup=!0):t.setValuesActive(r),c.groupName&&H.trigger("expandValuesGroup",c.groupName),t.setState(o?{}:{activeValues:s}),t.triggerValuesChange("create")}else Q.showSystemError(a)})}},showEditRules:function(e){this.currentFocusRules=e;var t=this.state.rules,n=e||t.getActive();if(n&&!n.isDefault){var r=Se(this.refs.editRulesInput);r.value=n.name,this.setState({showEditRules:!0,selectedRule:n},function(){r.select(),r.focus()})}},showEditValuesByDBClick:function(e){!e.changed&&this.showEditValues()},showEditValues:function(e){this.currentFocusValues=e;var t=this.state.values,n=e||t.getActive();if(n&&!n.isDefault){var r=Se(this.refs.editValuesInput);r.value=n.name,this.setState({showEditValues:!0,selectedValue:n},function(){r.select(),r.focus()})}},editRules:function(e){if(13==e.keyCode||"click"==e.type){var t=this,n=t.state.rules,r=this.currentFocusRules||n.getActive();if(r){var o=Se(t.refs.editRulesInput),i=Q.isGroup(r.name),a=(i?"\r":"")+o.value.trim();if(!a)return void G.error("The name is required");if(n.exists(a))return void G.error("The name '"+a+"' is already in use");var s=r.name;z.rules.rename({name:s,newName:a},function(e,r){e&&0===e.ec?(n.rename(s,a),o.value="",o.blur(),!i&&t.setRulesActive(a),H.trigger("rulesNameChanged",[s,a]),t.setState({activeRules:n.getActive()}),t.triggerRulesChange("rename")):Q.showSystemError(r)})}}},editValues:function(e){if(13==e.keyCode||"click"==e.type){var t=this,n=t.state.values,r=this.currentFocusValues||n.getActive();if(r){var o=Se(t.refs.editValuesInput),i=Q.isGroup(r.name),a=(i?"\r":"")+o.value.trim();if(!a)return void G.error("The name is required");if(n.exists(a))return void G.error("The name '"+a+"' is already in use");var s=r.name;z.values.rename({name:s,newName:a},function(e,r){e&&0===e.ec?(n.rename(s,a),o.value="",o.blur(),!i&&t.setValuesActive(a),H.trigger("valuesNameChanged",[s,a]),t.setState({activeValues:n.getActive()}),t.triggerValuesChange("rename")):Q.showSystemError(r)})}}},getActiveRuleName:function(){var e=this.state.rules,t=e.getActive();return t?t.name:""},showAnonymousWeinre:function(){this.openWeinre()},showWeinre:function(e){this.openWeinre(e.name)},openWeinre:function(e){window.open("weinre/client/#"+(e||"anonymous")),this.setState({showWeinreOptions:!1})},onClickRulesOption:function(e){e.selected?this.unselectRules(e):this.selectRules(e)},selectRules:function(e){if(!Q.isGroup(e.name)){var t=this;return z.rules[e.isDefault?"enableDefault":"select"](e,function(n,r){n&&0===n.ec?(t.reselectRules(n),t.state.rules.setChanged(e.name,!1),t.setState({}),t.triggerRulesChange("save"),n.changed&&H.trigger("rulesChanged"),t.state.disabledAllRules&&ee.confirm("Rules are currently disabled. Enable them now?",function(e){e&&z.rules.disableAllRules({disabledAllRules:0},function(e,n){e&&0===e.ec?(t.state.disabledAllRules=!1,t.setState({})):Q.showSystemError(n)})})):Q.showSystemError(r)}),!1}},selectRulesByOptions:function(e){var t=this.state.rules.data[y(e.target).attr("data-name")];this[e.target.checked?"selectRules":"unselectRules"](t)},unselectRules:function(e){var t=this;return z.rules[e.isDefault?"disableDefault":"unselect"](e,function(e,n){e&&0===e.ec?(t.reselectRules(e),t.triggerRulesChange("unselect"),t.setState({})):Q.showSystemError(n)}),!1},reselectRules:function(e,t){var n=this;n.state.rules.clearAllSelected(),n.setSelected(n.state.rules,"Default",!e.defaultRulesIsDisabled,t),e.list.forEach(function(e){n.setSelected(n.state.rules,e,!0,t)})},saveValues:function(e){if(e.changed&&!Q.isGroup(e.name)){var t=this;return z.values.add(e,function(n,r){n&&0===n.ec?(t.setSelected(t.state.values,e.name),t.triggerValuesChange("save")):Q.showSystemError(r)}),!1}},setSelected:function(e,t,n,r){e.setSelected(t,n)&&(r||e.setChanged(t,!1),this.setState({curSelectedName:t}))},replayCountChange:function(e){var t=e.target.value.replace(/^\s*0*|[^\d]+/,""),n=t.slice(0,3);n>me&&(n=me),this.setState({replayCount:n})},clickReplay:function(e){e.shiftKey?H.trigger("replaySessions",[null,e.shiftKey]):this.replay(e)},replay:function(e,t,n){var r=this.state.network;if(t=Array.isArray(t)?t:r.getSelectedList(),t&&t.length){this.enableRecord();var o,i=function(e,t){var n=e.req;z.compose({repeatCount:t,useH2:e.useH2?1:"",url:e.url,headers:Q.getOriginalReqHeaders(e),method:n.method,base64:n.base64})};if(n>1?i(t[0],Math.min(n,me)):(o={},t.slice(0,me).forEach(function(e){o[e.id]=1,i(e)})),r.isTreeView){var a=z.lastSelectedDataId;if(!a)return;if(!o)return H.trigger("replayTreeView",[a,n]);var s=a&&r.getTreeNode(a);if(s=s&&s.parent,!s)return;n=0,s.children.forEach(function(e){e=e.data,e&&o[e.id]&&++n}),H.trigger("replayTreeView",[a,n])}else this.autoRefresh&&this.autoRefresh()}},enableRecord:function(){this.refs.recordBtn.enable(),H.trigger("changeRecordState")},composer:function(){H.trigger("composer")},clear:function(){var e=this.state.network;this.setState({network:e.clear()})},removeRulesBatch:function(e){var t=this;z.rules.remove({list:e},function(n,r){if(n&&0===n.ec){var o,i=t.state.rules;e.forEach(function(e){var n=i.data[e]||"";n.active&&(o=i.getSibling(e),o&&t.setRulesActive(o.name)),i.remove(e)}),o&&H.trigger("expandRulesGroup",o.name),t.setState(o?{activeRules:o}:{}),t.triggerRulesChange("remove"),H.trigger("focusRulesList")}else Q.showSystemError(r)}),this.refs.deleteRulesDialog.hide()},removeValuesBatch:function(e){var t=this;z.values.remove({list:e},function(n,r){if(n&&0===n.ec){var o,i=t.state.values;e.forEach(function(e){var n=i.data[e]||"";n.active&&(o=i.getSibling(e),o&&t.setValuesActive(o.name)),i.remove(e)}),o&&H.trigger("expandValuesGroup",o.name),t.setState(o?{activeValues:o}:{}),t.triggerValuesChange("remove"),H.trigger("focusValuesList")}else Q.showSystemError(r)}),this.refs.deleteValuesDialog.hide()},removeRules:function(e){var t=this.state.rules,n=e||t.getActive();n&&!n.isDefault&&this.refs.deleteRulesDialog.show(n.name)},removeValues:function(e){var t=this.state.values,n=e||t.getActive();n&&!n.isDefault&&this.refs.deleteValuesDialog.show(n.name)},setRulesActive:function(e,t){t=t||this.state.rules,F.set("activeRules",e),t.setActive(e)},setValuesActive:function(e,t){t=t||this.state.values,F.set("activeValues",e),t.setActive(e)},showRulesSettings:function(){y(Se(this.refs.rulesSettingsDialog)).modal("show")},showValuesSettings:function(){y(Se(this.refs.valuesSettingsDialog)).modal("show")},toggleLeftMenu:function(){var e=!this.state.showLeftMenu;this.setState({showLeftMenu:e}),F.set("showLeftMenu",e?1:""),H.trigger("editorResize")},handleCreate:function(){"rules"==this.state.name?this.showCreateRules():this.showCreateValues()},saveRulesOrValues:function(){var e,t=this,n=t.state,r="rules"==n.name;if(r){e=n.rules.getChangedList();var o=n.rules.getActive();o&&!o.selected&&-1===e.indexOf(o)&&e.push(o),e.length&&(e.forEach(function(e){t.selectRules(e)}),t.setState({}))}else e=n.values.getChangedList(),e.length&&(e.forEach(function(e){t.saveValues(e)}),t.setState({}))},onClickMenu:function(e){var t=y(e.target).closest("a"),n=this,r=n.state,o="rules"==r.name;t.hasClass("w-edit-menu")?o?n.showEditRules():n.showEditValues():t.hasClass("w-delete-menu")?o?n.removeRules():n.removeValues():t.hasClass("w-save-menu")&&n.saveRulesOrValues()},showSettings:function(){var e=this.state.name;return"rules"===e?void this.showRulesSettings():"values"===e?void this.showValuesSettings():void("network"===e&&this.refs.networkSettings.showDialog())},activeRules:function(e){F.set("activeRules",e.name),this.setState({activeRules:e})},activeValues:function(e){F.set("activeValues",e.name),this.setState({activeValues:e})},onRulesThemeChange:function(e){var t=e.target.value;F.set("rulesTheme",t),this.setState({rulesTheme:t})},onValuesThemeChange:function(e){var t=e.target.value;F.set("valuesTheme",t),this.setState({valuesTheme:t})},onRulesFontSizeChange:function(e){var t=e.target.value;F.set("rulesFontSize",t),this.setState({rulesFontSize:t})},onValuesFontSizeChange:function(e){var t=e.target.value;F.set("valuesFontSize",t),this.setState({valuesFontSize:t})},onRulesLineNumberChange:function(e){var t=e.target.checked;F.set("showRulesLineNumbers",t),this.setState({showRulesLineNumbers:t})},onValuesLineNumberChange:function(e){var t=e.target.checked;F.set("showValuesLineNumbers",t),this.setState({showValuesLineNumbers:t})},showFoldGutter:function(e){var t=e.target.checked;F.set("foldGutter",t?"1":""),this.setState({foldGutter:t})},onRulesLineWrappingChange:function(e){var t=e.target.checked;F.set("autoRulesLineWrapping",t?1:""),this.setState({autoRulesLineWrapping:t})},onValuesLineWrappingChange:function(e){var t=e.target.checked;F.set("autoValuesLineWrapping",t?1:""),this.setState({autoValuesLineWrapping:t})},confirmDisableAllRules:function(e){var t,n=this,r=n.state;r.disabledAllRules||!e&&(t=y(".w-win-dialog[data-confirm-flag=rules]")).is(":visible")?(n.disableAllRules(),t&&t.modal("hide")):ee.confirm("Do you confirm disabling all rules?",function(e){e&&n.disableAllRules()},!1,"rules"),e&&e.preventDefault()},confirmDisableAllPlugins:function(e){var t,n=this,r=n.state;r.disabledAllPlugins||!e&&(t=y(".w-win-dialog[data-confirm-flag=plugins]")).is(":visible")?(n.disableAllPlugins(),t&&t.modal("hide")):ee.confirm("Do you confirm disabling all plugins?",function(e){e&&n.disableAllPlugins()},!1,"plugins"),e&&e.preventDefault()},disableAllRules:function(e,t){var n=this,r=n.state,o=!r.disabledAllRules;z.rules.disableAllRules({disabledAllRules:o?1:0},function(e,i){e&&0===e.ec?(r.disabledAllRules=o,n.setState({}),"function"==typeof t&&t(o)):Q.showSystemError(i)}),e&&e.preventDefault()},disableAllPlugins:function(e,t){var n=this,r=n.state,o=!r.disabledAllPlugins;z.plugins.disableAllPlugins({disabledAllPlugins:o?1:0},function(e,i){e&&0===e.ec?(r.disabledAllPlugins=o,O.setPlugins(r),n.setState({}),"function"==typeof t&&t(o)):Q.showSystemError(i)}),e&&e.preventDefault()},setPluginState:function(e,t){var n=this;return n.state.ndp?G.info("Plugin disabling is restricted"):void z.plugins.disablePlugin({name:e,disabled:t?1:0},function(e,t){e&&0===e.ec?(n.state.disabledPlugins=e.data,z.setDisabledPlugins(e.data),O.setPlugins(n.state),n.setState({})):Q.showSystemError(t)})},disablePlugin:function(e){var t=e.target;this.setPluginState(y(t).attr("data-name"),!t.checked)},abort:function(e){if(!Array.isArray(e)){var t=this.state.network;e=t.getSelectedList()}e&&(e=e.map(function(e){return Q.canAbort(e)?e.id:void 0}),e.length&&z.abort({list:e.join()})),this.hideAbortOptions()},allowMultipleChoice:function(e){this.setMultipleCohice(e.target.checked)},setMultipleCohice:function(e){var t=this;z.rules.allowMultipleChoice({allowMultipleChoice:e?1:0},function(n,r){n&&0===n.ec?t.setState({allowMultipleChoice:e}):Q.showSystemError(r)})},enableBackRulesFirst:function(e){this.setBackRulesFirst(e.target.checked)},setBackRulesFirst:function(e){var t=this;z.rules.enableBackRulesFirst({backRulesFirst:e?1:0},function(n,r){n&&0===n.ec?(t.setState({backRulesFirst:e}),z.backRulesFirst=e):Q.showSystemError(r)})},installPlugins:function(){H.trigger("installPlugins")},chooseFileType:function(e){var t=e.target.value;F.set("exportFileType",t),this.setState({exportFileType:t})},importHarSessions:function(e){if(e&&"object"===("undefined"==typeof e?"undefined":M(e))){var t=e.log.entries,n=[];t.forEach(function(e){e=Q.harToSession(e),e&&n.push(e)}),z.addNetworkList(n)}},uploadSessionsForm:function(e){if(!(e instanceof FormData)){var t=new FormData;t.append("importSessions",e),e=t}var n=e.get("importSessions");if(!n||!/\.(txt|json|saz|har)$/i.test(n.name))return ee.alert("Supported file formats: .txt, .json, .saz, .har");if(n.size>he)return ee.alert("Maximum file size: 64MB");var r=/\.(?:txt|json)$/i.test(n.name);if(r||/\.har$/i.test(n.name)){var o=this;return void Q.readFileAsText(n,function(e){try{e=JSON.parse(e),r?z.importAnySessions(e):o.importHarSessions(e)}catch(t){ee.alert("Invalid JSON format")}})}z.upload.importSessions(e,z.addNetworkList)},getExportSessions:function(){var e=this.state.network,t=this.currentFoucsItem;return this.currentFoucsItem=null,t&&y(Se(this.refs.chooseFileType)).is(":visible")||(t=e.getSelectedList()),t},exportSessions:function(e,t,n){if(n=n||this.getExportSessions(),n&&n.length){var r=Se(this.refs.exportSessionsForm);Se(this.refs.exportFilename).value=t||"",Se(this.refs.exportFileType).value=e,"har"===e&&(n={log:{version:"1.2",creator:{name:"Whistle",version:this.state.version,comment:""},browser:{name:"Whistle",version:this.state.version},pages:[],entries:n.map(Q.toHar),comment:""}}),Se(this.refs.sessions).value=JSON.stringify(n,null," "),r.submit()}},hideChooseFileTypeDialog:function(e){e||(y(Se(this.refs.chooseFileType)).modal("hide"),Se(this.refs.sessionsName).value="")},exportBySave:function(e){if(!e||"click"===e.type||13===e.keyCode){var t=Se(this.refs.sessionsName),n=t.value.trim();t.value="",this.exportSessions(this.state.exportFileType,n),this.hideChooseFileTypeDialog()}},replayRepeat:function(e){e&&"click"!==e.type&&13!==e.keyCode||(this.refs.setReplayCount.hide(),this.replay("",this.replayList,this.state.replayCount),H.trigger("focusNetworkList"))},showAboutDialog:function(e){this.state.hasNewVersion&&(this.refs.aboutDialog.showAboutInfo(),e.preventDefault())},onTopContextMenu:function(e){if("network"===this.getTabName()&&!y(e.target).closest(".w-menu-item").length){e.preventDefault();var t=Q.getMenuPosition(e,110,100);t.list=Le,this.refs.topContextMenu.show(t)}},onContextMenu:function(e){var t=0,n=ke;if(n[2].hide&&++t,n[3].hide&&++t,n[4].hide&&++t,3>t){var r=Q.getMenuPosition(e,110,100-30*t),o=this.state;r.list=n,n[2].checked=!!o.network.isTreeView,n[3].checked=!o.disabledAllRules,n[4].checked=!o.disabledAllPlugins;var i=y(e.target);n[0].hide=!0,n[1].hide=!0,i.closest(".w-network-menu").length?n[0].hide=!1:i.closest(".w-save-menu").length&&(n[1].hide=!1,i.closest(".w-rules-menu").length?n[1].disabled=!o.rules.hasChanged():n[1].disabled=!o.values.hasChanged()),this.refs.contextMenu.show(r)}e.preventDefault()},onClickTopMenu:function(e){switch(e){case"top":this.container&&(this.container[0].scrollTop=0);break;case"selected":H.trigger("ensureSelectedItemVisible");break;case"bottom":this.container&&(this.container[0].scrollTop=1e7)}},onClickContextMenu:function(e){var t=this,n=t.state,r=ke;switch(e){case"Tree View":r[2].checked=!n.network.isTreeView,setTimeout(t.toggleTreeView,0);break;case"Rules":t.disableAllRules(null,function(e){r[3].checked=!e,t.setState({})});break;case"Plugins":t.disableAllPlugins(null,function(e){r[4].checked=!e,t.setState({})});break;case"Clear":return void t.clear();case"Save":return void t.saveRulesOrValues()}this.refs.contextMenu.show({})},forceShowLeftMenu:function(){var e=this;clearTimeout(e.hideTimer),clearTimeout(e.showTimer),e.showTimer=setTimeout(function(){e.setState({forceShowLeftMenu:!0})},200)},forceHideLeftMenu:function(){var e=this;clearTimeout(e.hideTimer),clearTimeout(e.showTimer),e.hideTimer=setTimeout(function(){e.setState({forceShowLeftMenu:!1})},500)},updateMenuView:function(e){var t=e.networkOptions[e.networkOptions.length-1];return e.network.isTreeView?(t.icon="globe",t.name="Show List View"):(t.icon="tree-conifer",t.name="Show Tree View"),e},toggleTreeView:function(){var e=this,t=e.state.network;t.setTreeView(!t.isTreeView),e.updateMenuView(e.state),e.setState({},function(){t.isTreeView||e.autoRefresh&&e.autoRefresh()})},toggleTreeViewByIcon:function(){"network"==this.getTabName()&&this.toggleTreeView()},download:function(e){if(e&&(Q.isString(e.content)||Q.isString(e.value)||Q.isString(e.base64))){var t=Q.getString(e.base64);Se(this.refs.filename).value=Q.getString(e.name),Se(this.refs.dataType).value=t?"rawBase64":"",Se(this.refs.content).value=t||Q.getString(e.value||e.content),Se(this.refs.downloadForm).submit()}},getTabName:function(){var e=this.state,t=e.rulesMode,n=e.pluginsMode,r=e.name;return e.networkMode?r="network":e.rulesOnlyMode?r="values"===r?"values":"rules":t&&n?r="plugins":t?r="network"===r?"rules":r:n&&(r="plugins"!==r?"network":r),r||"network"},isHideRules:function(){return this.state.networkMode||this.state.pluginsMode},onClickHelpMenu:function(e,t){"Update"===e.name&&z.showLatestClientVersion()&&t.preventDefault()},render:function(){var e=this.state,t=e.networkMode,n=e.rulesMode,o=e.rulesOnlyMode,i=e.pluginsMode,a=z.isMultiEnv(),s=this.getTabName(),l="account"==s,c="network"==s,u="rules"==s,d="values"==s,p="plugins"==s,h=u||d,g=r(!h),f=r(p||l),m=!0,M=!0,v=e.rulesTheme||"cobalt",b=e.valuesTheme||"cobalt",y=e.rulesFontSize||"14px",T=e.valuesFontSize||"14px",C=e.showRulesLineNumbers||!1,E=e.showValuesLineNumbers||!1,O=e.autoRulesLineWrapping,H=e.autoValuesLineWrapping,F=e.rulesOptions,G=e.pluginsOptions,ee={},ce=e.showNetworkOptions,ue=e.showRulesOptions,pe=e.showValuesOptions,he=e.showPluginsOptions,ge=e.showWeinreOptions,fe=e.showHelpOptions,Ae=e.network,Me=Ae.isTreeView,we=(Me?"tree-conifer":"globe")+(e.record?" w-disabled":"");F[0].name===de&&F.forEach(function(e,t){e.icon=t&&a?"edit":"checkbox",e.selected||(ee[e.name]=1)});var ye,xe;if(u){xe=e.rules.data;for(ye in xe)if(xe[ye].active){m=M=xe[ye].isDefault;break}}else if(d){xe=e.values.data;for(ye in xe)if(xe[ye].active){m=M=!1;break}}Ae.rulesModal=e.rules,e.rules.editorTheme={theme:v,fontSize:y,lineNumbers:C};var Te=e.networkOptions,Ce=Ae.hasUnselected();Ae.hasSelected()?Te.forEach(function(e){e.disabled=!1,"removeUnselected"===e.id&&(e.disabled=!Ce)}):(Te.forEach(function(e){-1!==ve.indexOf(e.id)?e.disabled=!0:"removeUnselected"===e.id&&(e.disabled=!Ce)}),Te[0].disabled=!Ce);var Ee,De,Se=w&&!e.forceShowLeftMenu,Le=i&&n,je=(t||e.showLeftMenu)&&!Le,Ue=e.disabledAllPlugins,Re=e.disabledAllRules,ze=r(o||Le||t);je&&w&&(Ee=this.forceShowLeftMenu,De=this.forceHideLeftMenu),ke[2].hide=n,ke[3].hide=i,ke[4].hide=o;var Qe=e.caType||"crt",Oe=e.caHash,He="cgi-bin/rootca",Fe="http://rootca.pro/";"cer"!==Qe&&(He+="?type="+Qe,Fe+=Qe);var Ve=this.isHideRules(),Pe=r(Ve),Ye=Ie?" hide":"";return z.hideMockMenu=Ve,this.hideNetwork=n,this.hideRules=this.hideValues=Ve, this.hidePlugins=ze,x.createElement("div",{className:"main v-box"+(je?" w-show-left-menu":"")+(h&&!o?" w-show-editor":"")+(u?" w-show-rules":"")+(o||n?" w-show-rules-mode":"")},x.createElement("div",{className:"w-menu w-"+s+"-menu-list"+Ye+(je?"":" w-top"),onContextMenu:this.onTopContextMenu},x.createElement("a",{onClick:this.toggleLeftMenu,draggable:"false",className:"w-switch-layout",onMouseEnter:Ee,onMouseLeave:De,style:r(t||Le),title:"Ctrl[Command] + M"},x.createElement(se,{name:"chevron-"+(je?Se?"down":"up":"left")})),x.createElement("div",{style:r(n),onMouseEnter:this.showNetworkOptions,onMouseLeave:this.hideNetworkOptions,className:"w-nav-menu w-menu-wrapper"+(ce?" w-menu-wrapper-show":"")},x.createElement("a",{onClick:this.showNetwork,onDoubleClick:this.toggleTreeView,className:"w-network-menu"+(c?" w-menu-selected":""),title:"Double-click to open"+(Me?" List View":" Tree View"),draggable:"false"},x.createElement(se,{name:we}),"Network"),x.createElement(k,{ref:"networkMenuItem",options:e.networkOptions,className:"w-network-menu-item",onClickOption:this.handleNetwork})),x.createElement("div",{style:Pe,onMouseEnter:this.showRulesOptions,onMouseLeave:this.hideRulesOptions,className:"w-nav-menu w-menu-wrapper"+(ue?" w-menu-wrapper-show":"")+(u?" w-menu-auto":"")},x.createElement("a",{onClick:this.showRules,className:"w-rules-menu"+(u?" w-menu-selected":""),draggable:"false"},x.createElement(se,{name:"list",className:Re?"w-disabled":""}),"Rules"),x.createElement(k,{ref:"rulesMenuItem",name:u?null:"Open",options:F,checkedOptions:ee,disabled:Re,className:"w-rules-menu-item",onClick:this.showRules,onClickOption:this.showAndActiveRules,onChange:this.selectRulesByOptions})),x.createElement("div",{style:Pe,onMouseEnter:this.showValuesOptions,onMouseLeave:this.hideValuesOptions,className:"w-nav-menu w-menu-wrapper"+(pe?" w-menu-wrapper-show":"")+(d?" w-menu-auto":"")},x.createElement("a",{onClick:this.showValues,className:"w-values-menu"+(d?" w-menu-selected":""),draggable:"false"},x.createElement(se,{name:"folder-close"}),"Values"),x.createElement(k,{ref:"valuesMenuItem",name:d?null:"Open",options:e.valuesOptions,className:"w-values-menu-item",onClick:this.showValues,onClickOption:this.showAndActiveValues})),x.createElement("div",{style:ze,ref:"pluginsMenu",onMouseEnter:this.showPluginsOptions,onMouseLeave:this.hidePluginsOptions,className:"w-nav-menu w-menu-wrapper"+(he?" w-menu-wrapper-show":"")},x.createElement("a",{onClick:this.showPlugins,className:"w-plugins-menu"+(p?" w-menu-selected":""),draggable:"false"},x.createElement(se,{name:"th-large",className:Ue?"w-disabled":""}),"Plugins"),x.createElement(k,{ref:"pluginsMenuItem",name:p?null:"Open",options:G,checkedOptions:e.disabledPlugins,disabled:Ue,className:"w-plugins-menu-item",onClick:this.showPlugins,onChange:this.disablePlugin,onClickOption:this.showAndActivePlugins})),!e.ndr&&x.createElement("a",{onClick:this.confirmDisableAllRules,className:"w-enable-rules-menu w-switch-btn",title:Re?"Enable all rules":"Disable all rules",style:r(!u),draggable:"false"},x.createElement(se,{name:"stop",className:Re?"w-pause":""}),"ON"),!e.ndp&&x.createElement("a",{onClick:this.confirmDisableAllPlugins,className:"w-enable-plugin-menu w-switch-btn",title:Ue?"Enable all plugins":"Disable all plugins",style:r(!p),draggable:"false"},x.createElement(se,{name:"stop",className:Ue?"w-pause":""}),"ON"),x.createElement(W,{hide:!p}),x.createElement("a",{onClick:this.installPlugins,className:"w-plugins-menu",style:r(!p),draggable:"false"},x.createElement(se,{name:"download-alt"}),"Install"),x.createElement(j,{ref:"recordBtn",hide:!c,onClick:this.handleAction}),x.createElement("a",{onClick:this.importData,style:f,className:"w-import-menu",draggable:"false"},x.createElement(se,{name:"import"}),"Import"),x.createElement("a",{onClick:this.exportData,className:"w-export-menu",style:f,draggable:"false"},x.createElement(se,{name:"export"}),"Export"),x.createElement("a",{onClick:this.clear,style:r(!c),className:"w-remove-menu w-remove-menu-list",title:"Ctrl[Command] + X",draggable:"false"},x.createElement(se,{name:"remove"}),"Clear"),x.createElement("a",{onClick:this.onClickMenu,className:"w-save-menu",style:g,draggable:"false",title:"Ctrl[Command] + S"},x.createElement(se,{name:"save-file"}),"Save"),x.createElement("a",{className:"w-create-menu",style:g,draggable:"false",onClick:this.handleCreate},x.createElement(se,{name:"plus"}),"Create"),x.createElement("a",{onClick:this.onClickMenu,className:"w-edit-menu"+(m?" w-disabled":""),style:g,draggable:"false"},x.createElement(se,{name:"transfer"}),"Rename"),x.createElement("div",{onMouseEnter:this.showAbortOptions,onMouseLeave:this.hideAbortOptions,style:r(!c),className:"w-menu-wrapper w-abort-menu-list w-menu-auto"+(e.showAbortOptions?" w-menu-wrapper-show":"")},x.createElement("a",{onClick:this.clickReplay,className:"w-replay-menu",draggable:"false"},x.createElement(se,{name:"repeat"}),"Replay"),x.createElement(k,{options:Be,className:"w-remove-menu-item",onClickOption:this.abort})),x.createElement("a",{onClick:this.composer,className:"w-com-menu",style:r(!c),draggable:"false"},x.createElement(se,{name:"send"}),"Edit"),x.createElement("a",{onClick:this.onClickMenu,className:"w-delete-menu"+(M?" w-disabled":""),style:g,draggable:"false"},x.createElement(se,{name:"trash"}),"Delete"),x.createElement(Y,{onClick:this.showSettings,disabledRules:u&&Re,backRulesFirst:u&&e.backRulesFirst,isNetwork:c,hide:p}),x.createElement(te,{name:s}),x.createElement("div",{onMouseEnter:this.showWeinreOptions,onMouseLeave:this.hideWeinreOptions,className:"w-menu-wrapper"+(ge?" w-menu-wrapper-show":"")},x.createElement("a",{onClick:this.showWeinreOptionsQuick,onDoubleClick:this.showAnonymousWeinre,className:"w-weinre-menu",draggable:"false"},x.createElement(se,{name:"console"}),x.createElement("span",{className:"w-weinre-name"},"Weinre")),x.createElement(k,{ref:"weinreMenuItem",name:"anonymous",icon:"console",options:e.weinreOptions,className:"w-weinre-menu-item",onClick:this.showAnonymousWeinre,onClickOption:this.showWeinre})),x.createElement("a",{onClick:this.showHttpsSettingsDialog,className:"w-https-menu",draggable:"false",style:{color:z.hasInvalidCerts?"var(--c-error)":void 0}},x.createElement(se,{name:e.interceptHttpsConnects?"ok-circle":"lock"}),x.createElement("span",{className:"w-https-name"},"HTTPS")),x.createElement("div",{onMouseEnter:this.showHelpOptions,onMouseLeave:this.hideHelpOptions,className:"w-menu-wrapper"+(fe?" w-menu-wrapper-show":"")},x.createElement("a",{onClick:this.showAboutDialog,title:e.hasNewVersion?"A new version is available, click to see details":void 0,href:"https://github.com/avwo/whistle#whistle",target:"_blank"},e.hasNewVersion?x.createElement("i",{className:"w-new-version-icon"}):null,x.createElement(se,{name:"question-sign"}),x.createElement("span",{className:"w-help-name"},"Help")),x.createElement(k,{ref:"helpMenuItem",options:e.helpOptions,onClickOption:this.onClickHelpMenu,name:x.createElement(S,{ref:"aboutDialog",clientVersion:Ne,onClick:this.hideHelpOptions,onCheckUpdate:this.showHasNewVersion}),className:"w-help-menu-item"})),x.createElement(L,{name:s,clientVersion:Ne}),x.createElement("div",{onMouseDown:this.preventBlur,style:{display:e.showCreateRules?"block":"none"},className:"w-shadow w-input-menu-item w-create-rules-input"},x.createElement("input",{ref:"createRulesInput",onKeyDown:this.createRules,onBlur:this.hideRulesInput,type:"text",maxLength:"64",placeholder:"Enter name"}),x.createElement("button",{type:"button",onClick:this.createRules,className:"btn btn-primary"},"+Rule"),x.createElement("button",{type:"button",onClick:this.createRules,"data-type":"top",className:"btn btn-default"},"+Top"),x.createElement("button",{type:"button",onClick:this.createRules,"data-type":"group",className:"btn btn-default"},"+Group")),x.createElement("div",{onMouseDown:this.preventBlur,style:{display:e.showCreateValues?"block":"none"},className:"w-shadow w-input-menu-item w-create-values-input"},x.createElement("input",{ref:"createValuesInput",onKeyDown:this.createValues,onBlur:this.hideValuesInput,type:"text",maxLength:"64",placeholder:"Enter name"}),x.createElement("button",{type:"button",onClick:this.createValues,className:"btn btn-primary"},"+Key"),x.createElement("button",{type:"button",onClick:this.createValues,"data-type":"group",className:"btn btn-default"},"+Group")),x.createElement("div",{onMouseDown:this.preventBlur,style:{display:e.showEditRules?"block":"none"},className:"w-shadow w-input-menu-item w-edit-rules-input"},x.createElement("input",{ref:"editRulesInput",onKeyDown:this.editRules,onBlur:this.hideRenameRuleInput,type:"text",maxLength:"64"}),x.createElement("button",{type:"button",onClick:this.editRules,className:"btn btn-primary"},"OK")),x.createElement("div",{onMouseDown:this.preventBlur,style:{display:e.showEditValues?"block":"none"},className:"w-shadow w-input-menu-item w-edit-values-input"},x.createElement("input",{ref:"editValuesInput",onKeyDown:this.editValues,onBlur:this.hideRenameValueInput,type:"text",maxLength:"64"}),x.createElement("button",{type:"button",onClick:this.editValues,className:"btn btn-primary"},"OK"))),x.createElement("div",{className:"w-container box fill"},x.createElement(X,{onClick:this.onClickContextMenu,ref:"contextMenu"}),x.createElement(X,{onClick:this.onClickTopMenu,ref:"topContextMenu"}),x.createElement("div",{onContextMenu:this.onContextMenu,onDoubleClick:this.onContextMenu,className:"w-left-menu"+(Ee?" w-hover-left-menu":"")+Ye,style:r(t||Se),onMouseEnter:Ee,onMouseLeave:De},x.createElement("a",{onClick:this.showNetwork,className:"w-network-menu"+(c?" w-menu-selected":""),style:r(n),draggable:"false"},x.createElement(se,{name:we}),x.createElement("i",{className:"w-left-menu-name"},"Network")),x.createElement("a",{onClick:this.showRules,className:"w-save-menu w-rules-menu"+(u?" w-menu-selected":""),style:Pe,draggable:"false"},x.createElement(se,{name:"list",className:Re?"w-disabled":""}),x.createElement("i",{className:"w-left-menu-name"},"Rules"),x.createElement("i",{className:"w-menu-changed",style:r(!e.rules.hasChanged())},"*")),x.createElement("a",{onClick:this.showValues,className:"w-save-menu w-values-menu"+(d?" w-menu-selected":""),style:Pe,draggable:"false"},x.createElement(se,{name:"folder-close"}),x.createElement("i",{className:"w-left-menu-name"},"Values"),x.createElement("i",{className:"w-menu-changed",style:r(!e.values.hasChanged())},"*")),x.createElement("a",{onClick:this.showPlugins,className:"w-plugins-menu"+(p?" w-menu-selected":""),style:ze,draggable:"false"},x.createElement(se,{name:"th-large",className:Ue?"w-disabled":""}),x.createElement("i",{className:"w-left-menu-name"},"Plugins"))),e.hasRules?x.createElement(I,{ref:"rules",disabled:Re,theme:v,lineWrapping:O,fontSize:y,lineNumbers:C,onSelect:this.selectRules,onUnselect:this.unselectRules,onActive:this.activeRules,modal:e.rules,hide:!u,name:"rules"}):void 0,e.hasValues?x.createElement(I,{theme:b,onDoubleClick:this.showEditValuesByDBClick,fontSize:T,lineWrapping:H,lineNumbers:E,onSelect:this.saveValues,onActive:this.activeValues,modal:e.values,hide:!d,className:"w-values-list",foldGutter:e.foldGutter}):void 0,e.hasNetwork?x.createElement(D,{ref:"network",hide:!c,modal:Ae,rulesModal:e.rules}):void 0,e.hasPlugins?x.createElement(R,A({},e,{onOpen:this.activePluginTab,onClose:this.closePluginTab,onActive:this.activePluginTab,onChange:this.disablePlugin,ref:"plugins",hide:!p})):void 0),x.createElement("div",{ref:"rulesSettingsDialog",className:"modal fade w-rules-settings-dialog"},x.createElement("div",{className:"modal-dialog"},x.createElement("div",{className:"modal-content"},x.createElement("div",{className:"modal-body"},x.createElement(le,null),x.createElement(U,{name:"rules",theme:v,fontSize:y,lineNumbers:C,lineWrapping:O,onLineWrappingChange:this.onRulesLineWrappingChange,onThemeChange:this.onRulesThemeChange,onFontSizeChange:this.onRulesFontSizeChange,onLineNumberChange:this.onRulesLineNumberChange}),!e.drm&&x.createElement("p",{className:"w-editor-settings-box"},x.createElement("label",{className:"w-align-items",style:{color:a?"var(--c-disabled)":void 0}},x.createElement("input",{type:"checkbox",disabled:a,checked:!a&&e.allowMultipleChoice,onChange:this.allowMultipleChoice})," ","Use multiple rules")),!e.drb&&x.createElement("p",{className:"w-editor-settings-box"},x.createElement("label",{className:"w-align-items"},x.createElement("input",{type:"checkbox",checked:e.backRulesFirst,onChange:this.enableBackRulesFirst})," ","The later rules first"))),x.createElement("div",{className:"modal-footer"},x.createElement("button",{type:"button",className:"btn btn-default","data-dismiss":"modal"},"Close"),x.createElement("button",{type:"button",className:"btn btn-primary",onClick:this.importRulesSettings},"Import"),x.createElement("button",{type:"button",className:"btn btn-info",onClick:this.exportRulesSettings},"Export"))))),x.createElement("div",{ref:"valuesSettingsDialog",className:"modal fade w-values-settings-dialog"},x.createElement("div",{className:"modal-dialog"},x.createElement("div",{className:"modal-content"},x.createElement("div",{className:"modal-body"},x.createElement(le,null),x.createElement(U,{theme:b,fontSize:T,lineNumbers:E,lineWrapping:H,onLineWrappingChange:this.onValuesLineWrappingChange,onThemeChange:this.onValuesThemeChange,onFontSizeChange:this.onValuesFontSizeChange,onLineNumberChange:this.onValuesLineNumberChange}),x.createElement("p",{className:"w-editor-settings-box"},x.createElement("label",{className:"w-align-items"},x.createElement("input",{type:"checkbox",checked:e.foldGutter,onChange:this.showFoldGutter})," ","Show fold gutter"))),x.createElement("div",{className:"modal-footer"},x.createElement("button",{type:"button",className:"btn btn-default","data-dismiss":"modal"},"Close"),x.createElement("button",{type:"button",className:"btn btn-primary",onClick:this.importValuesSettings},"Import"),x.createElement("button",{type:"button",className:"btn btn-info",onClick:this.exportValuesSettings},"Export"))))),n?null:x.createElement(B,{ref:"networkSettings"}),x.createElement(ie,{ref:"httpsSettings",caHash:Oe,port:e.port,caUrlList:e.caUrlList,multiEnv:a,interceptHttpsConnects:e.interceptHttpsConnects,enableHttp2:e.enableHttp2,onEnableHttps:this.interceptHttpsConnects,onEnableHttp2:this.enableHttp2}),x.createElement("div",{ref:"chooseFileType",className:"modal fade w-choose-filte-type"},x.createElement("div",{className:"modal-dialog"},x.createElement("div",{className:"modal-content"},x.createElement("div",{className:"modal-body"},x.createElement("label",{className:"w-choose-filte-type-label"},"Save as:",x.createElement("input",{ref:"sessionsName",value:e.filename,onChange:this.filterFilename,onKeyDown:this.exportBySave,placeholder:"Enter filename (optional)",className:"form-control",maxLength:"64"}),x.createElement("select",{ref:"fileType",className:"form-control",value:e.exportFileType,onChange:this.chooseFileType},x.createElement("option",{value:"whistle"},"*.txt"),x.createElement("option",{value:"Fiddler"},"*.saz"),x.createElement("option",{value:"har"},"*.har")))),x.createElement("div",{className:"modal-footer"},x.createElement("button",{type:"button",className:"btn btn-default","data-dismiss":"modal"},"Cancel"),x.createElement(ne,{type:"network",onComplete:this.hideChooseFileTypeDialog,getFilename:this.getInputValue,data:this.getExportSessions}),x.createElement("button",{type:"button",onKeyDown:this.exportBySave,tabIndex:"0",onMouseDown:this.preventBlur,className:"btn btn-primary",onClick:this.exportBySave},"Export"))))),x.createElement(J,{ref:"editorWin",className:"w-editor-win"}),x.createElement(V,{ref:"setReplayCount",wstyle:"w-replay-count-dialog"},x.createElement("div",{className:"modal-body"},x.createElement("label",null,"Times:",x.createElement("input",{ref:"replayCount",placeholder:"<= "+me,onKeyDown:this.replayRepeat,onChange:this.replayCountChange,value:e.replayCount,className:"form-control",maxLength:"3"})),x.createElement("button",{type:"button",onKeyDown:this.replayRepeat,tabIndex:"0",onMouseDown:this.preventBlur,className:"btn btn-primary",disabled:!e.replayCount,onClick:this.replayRepeat},"Replay"))),x.createElement("div",{ref:"showUpdateTipsDialog",className:"modal fade w-show-update-tips-dialog"},x.createElement("div",{className:"modal-dialog"},x.createElement("div",{className:"modal-content"},x.createElement("div",{className:"modal-body"},x.createElement(le,null),x.createElement("p",{className:"w-show-update-tips"},"Whistle has critical updates available. Update to the latest version immediately."),x.createElement("p",null,"Current version: ",e.version),x.createElement("p",null,"Latest version: ",e.latestVersion),x.createElement("p",null,"View change:"," ",x.createElement("a",{title:"Change log",href:"https://github.com/avwo/whistle/blob/master/CHANGELOG.md",target:"_blank"},"CHANGELOG.md"))),x.createElement("div",{className:"modal-footer"},x.createElement("button",{type:"button",className:"btn btn-default",onClick:this.donotShowAgain,"data-dismiss":"modal"},"Don't Show Again"),x.createElement("a",{type:"button",className:"btn btn-primary",onClick:this.hideUpdateTipsDialog,href:Q.UPDATE_URL,target:"_blank"},"View Update Guide"))))),x.createElement(V,{ref:"confirmReload",wstyle:"w-confirm-reload-dialog"},x.createElement("div",{className:"modal-body w-confirm-reload"},x.createElement(le,null),x.createElement("div",{className:"w-reload-data-tips"})),x.createElement("div",{className:"modal-footer"},x.createElement("button",{type:"button",className:"btn btn-default","data-dismiss":"modal"},"No"),x.createElement("button",{type:"button",className:"btn btn-primary",onClick:this.reloadData,"data-dismiss":"modal"},"Yes"))),x.createElement(P,{ref:"deleteRulesDialog",title:"Delete Rules",tips:"Do you confirm the deletion of all follow rules or group?",onConfirm:this.removeRulesBatch,name:"rules",isRules:"1",list:e.rules.list}),x.createElement(P,{ref:"deleteValuesDialog",title:"Delete Values",tips:"Do you confirm the deletion of all follow values or group?",onConfirm:this.removeValuesBatch,name:"values",list:e.values.list}),x.createElement(P,{ref:"selectRulesDialog",name:"rules",modal:e.rules,list:e.rules.list}),x.createElement(P,{ref:"selectValuesDialog",title:"Export Values",name:"values",list:e.values.list}),x.createElement("iframe",{name:"downloadTargetFrame",style:be}),x.createElement("form",{ref:"exportSessionsForm",action:"cgi-bin/sessions/export",style:be,method:"post",target:"downloadTargetFrame"},x.createElement("input",{ref:"exportFilename",name:"exportFilename",type:"hidden"}),x.createElement("input",{ref:"exportFileType",name:"exportFileType",type:"hidden"}),x.createElement("input",{ref:"sessions",name:"sessions",type:"hidden"})),x.createElement(q,{ref:"syncDialog"}),x.createElement(K,{ref:"jsonDialog"}),x.createElement("div",{id:"copyTextBtn",style:be}),x.createElement(Z,{ref:"mockDialog"}),x.createElement(_,{ref:"rulesDialog"}),x.createElement("form",{ref:"downloadForm",action:"cgi-bin/download",style:be,method:"post",target:"downloadTargetFrame"},x.createElement("input",{ref:"dataType",name:"type",type:"hidden"}),x.createElement("input",{ref:"filename",name:"filename",type:"hidden"}),x.createElement("input",{ref:"content",name:"content",type:"hidden"})),x.createElement($,{ref:"iframeDialog"}),x.createElement(re,{ref:"importDialog"}),x.createElement(oe,{ref:"exportDialog"}),x.createElement(N,{textEditor:!0,standalone:!0}),x.createElement(ae,null))}});z.getInitialData(function(e){T.render(x.createElement(Re,{modal:e}),document.getElementById("container"))})},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+/",h=0,g=p.length;g>h;++h)c[h]=p[h],u[p.charCodeAt(h)]=h;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,h=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("")},f=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 f(h(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 v,b=/[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}/g,y=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))}},x=function(e){return e.replace(b,y)},T=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("")},C=n.atob&&"function"==typeof n.atob?function(e){return n.atob(e)}:function(e){return e.replace(/\S{1,4}/g,T)},N=function(e){return C(String(e).replace(/[^A-Za-z0-9\+\/]/g,""))},I=function(e){return x(C(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&&(v=function(e){return Uint8Array.from(N(E(e)),function(e){return e.charCodeAt(0)})});var S=function(){var e=n.Base64;return n.Base64=a,e};if(n.Base64={VERSION:s,atob:N,btoa:f,fromBase64:D,toBase64:M,utob:h,encode:M,encodeURI:w,btou:x,decode:D,noConflict:S,fromUint8Array:i,toUint8Array:v},"function"==typeof Object.defineProperty){var L=function(e){return{value:e,enumerable:!1,writable:!0,configurable:!0}};n.Base64.extendString=function(){Object.defineProperty(String.prototype,"fromBase64",L(function(){return D(this)})),Object.defineProperty(String.prototype,"toBase64",L(function(e){return M(this,e)})),Object.defineProperty(String.prototype,"toBase64URI",L(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)}},function(e,t,n){"use strict";n(5),n(14),n(16),window.jQuery=n(18),n(19)},function(e,t,n){var r=n(6);"string"==typeof r&&(r=[[e.id,r,""]]);n(13)(r,{});r.locals&&(e.exports=r.locals)},function(e,t,n){t=e.exports=n(7)(),t.push([e.id,'/*!\n * Bootstrap v3.3.5 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:Glyphicons Halflings;src:url('+n(8)+");src:url("+n(8)+"?#iefix) format('embedded-opentype'),url("+n(9)+") format('woff2'),url("+n(10)+") format('woff'),url("+n(11)+") format('truetype'),url("+n(12)+'#glyphicons_halflingsregular) format(\'svg\')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:Glyphicons Halflings;font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"*"}.glyphicon-plus:before{content:"+"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\\20AC"}.glyphicon-minus:before{content:"\\2212"}.glyphicon-cloud:before{content:"\\2601"}.glyphicon-envelope:before{content:"\\2709"}.glyphicon-pencil:before{content:"\\270F"}.glyphicon-glass:before{content:"\\E001"}.glyphicon-music:before{content:"\\E002"}.glyphicon-search:before{content:"\\E003"}.glyphicon-heart:before{content:"\\E005"}.glyphicon-star:before{content:"\\E006"}.glyphicon-star-empty:before{content:"\\E007"}.glyphicon-user:before{content:"\\E008"}.glyphicon-film:before{content:"\\E009"}.glyphicon-th-large:before{content:"\\E010"}.glyphicon-th:before{content:"\\E011"}.glyphicon-th-list:before{content:"\\E012"}.glyphicon-ok:before{content:"\\E013"}.glyphicon-remove:before{content:"\\E014"}.glyphicon-zoom-in:before{content:"\\E015"}.glyphicon-zoom-out:before{content:"\\E016"}.glyphicon-off:before{content:"\\E017"}.glyphicon-signal:before{content:"\\E018"}.glyphicon-cog:before{content:"\\E019"}.glyphicon-trash:before{content:"\\E020"}.glyphicon-home:before{content:"\\E021"}.glyphicon-file:before{content:"\\E022"}.glyphicon-time:before{content:"\\E023"}.glyphicon-road:before{content:"\\E024"}.glyphicon-download-alt:before{content:"\\E025"}.glyphicon-download:before{content:"\\E026"}.glyphicon-upload:before{content:"\\E027"}.glyphicon-inbox:before{content:"\\E028"}.glyphicon-play-circle:before{content:"\\E029"}.glyphicon-repeat:before{content:"\\E030"}.glyphicon-refresh:before{content:"\\E031"}.glyphicon-list-alt:before{content:"\\E032"}.glyphicon-lock:before{content:"\\E033"}.glyphicon-flag:before{content:"\\E034"}.glyphicon-headphones:before{content:"\\E035"}.glyphicon-volume-off:before{content:"\\E036"}.glyphicon-volume-down:before{content:"\\E037"}.glyphicon-volume-up:before{content:"\\E038"}.glyphicon-qrcode:before{content:"\\E039"}.glyphicon-barcode:before{content:"\\E040"}.glyphicon-tag:before{content:"\\E041"}.glyphicon-tags:before{content:"\\E042"}.glyphicon-book:before{content:"\\E043"}.glyphicon-bookmark:before{content:"\\E044"}.glyphicon-print:before{content:"\\E045"}.glyphicon-camera:before{content:"\\E046"}.glyphicon-font:before{content:"\\E047"}.glyphicon-bold:before{content:"\\E048"}.glyphicon-italic:before{content:"\\E049"}.glyphicon-text-height:before{content:"\\E050"}.glyphicon-text-width:before{content:"\\E051"}.glyphicon-align-left:before{content:"\\E052"}.glyphicon-align-center:before{content:"\\E053"}.glyphicon-align-right:before{content:"\\E054"}.glyphicon-align-justify:before{content:"\\E055"}.glyphicon-list:before{content:"\\E056"}.glyphicon-indent-left:before{content:"\\E057"}.glyphicon-indent-right:before{content:"\\E058"}.glyphicon-facetime-video:before{content:"\\E059"}.glyphicon-picture:before{content:"\\E060"}.glyphicon-map-marker:before{content:"\\E062"}.glyphicon-adjust:before{content:"\\E063"}.glyphicon-tint:before{content:"\\E064"}.glyphicon-edit:before{content:"\\E065"}.glyphicon-share:before{content:"\\E066"}.glyphicon-check:before{content:"\\E067"}.glyphicon-move:before{content:"\\E068"}.glyphicon-step-backward:before{content:"\\E069"}.glyphicon-fast-backward:before{content:"\\E070"}.glyphicon-backward:before{content:"\\E071"}.glyphicon-play:before{content:"\\E072"}.glyphicon-pause:before{content:"\\E073"}.glyphicon-stop:before{content:"\\E074"}.glyphicon-forward:before{content:"\\E075"}.glyphicon-fast-forward:before{content:"\\E076"}.glyphicon-step-forward:before{content:"\\E077"}.glyphicon-eject:before{content:"\\E078"}.glyphicon-chevron-left:before{content:"\\E079"}.glyphicon-chevron-right:before{content:"\\E080"}.glyphicon-plus-sign:before{content:"\\E081"}.glyphicon-minus-sign:before{content:"\\E082"}.glyphicon-remove-sign:before{content:"\\E083"}.glyphicon-ok-sign:before{content:"\\E084"}.glyphicon-question-sign:before{content:"\\E085"}.glyphicon-info-sign:before{content:"\\E086"}.glyphicon-screenshot:before{content:"\\E087"}.glyphicon-remove-circle:before{content:"\\E088"}.glyphicon-ok-circle:before{content:"\\E089"}.glyphicon-ban-circle:before{content:"\\E090"}.glyphicon-arrow-left:before{content:"\\E091"}.glyphicon-arrow-right:before{content:"\\E092"}.glyphicon-arrow-up:before{content:"\\E093"}.glyphicon-arrow-down:before{content:"\\E094"}.glyphicon-share-alt:before{content:"\\E095"}.glyphicon-resize-full:before{content:"\\E096"}.glyphicon-resize-small:before{content:"\\E097"}.glyphicon-exclamation-sign:before{content:"\\E101"}.glyphicon-gift:before{content:"\\E102"}.glyphicon-leaf:before{content:"\\E103"}.glyphicon-fire:before{content:"\\E104"}.glyphicon-eye-open:before{content:"\\E105"}.glyphicon-eye-close:before{content:"\\E106"}.glyphicon-warning-sign:before{content:"\\E107"}.glyphicon-plane:before{content:"\\E108"}.glyphicon-calendar:before{content:"\\E109"}.glyphicon-random:before{content:"\\E110"}.glyphicon-comment:before{content:"\\E111"}.glyphicon-magnet:before{content:"\\E112"}.glyphicon-chevron-up:before{content:"\\E113"}.glyphicon-chevron-down:before{content:"\\E114"}.glyphicon-retweet:before{content:"\\E115"}.glyphicon-shopping-cart:before{content:"\\E116"}.glyphicon-folder-close:before{content:"\\E117"}.glyphicon-folder-open:before{content:"\\E118"}.glyphicon-resize-vertical:before{content:"\\E119"}.glyphicon-resize-horizontal:before{content:"\\E120"}.glyphicon-hdd:before{content:"\\E121"}.glyphicon-bullhorn:before{content:"\\E122"}.glyphicon-bell:before{content:"\\E123"}.glyphicon-certificate:before{content:"\\E124"}.glyphicon-thumbs-up:before{content:"\\E125"}.glyphicon-thumbs-down:before{content:"\\E126"}.glyphicon-hand-right:before{content:"\\E127"}.glyphicon-hand-left:before{content:"\\E128"}.glyphicon-hand-up:before{content:"\\E129"}.glyphicon-hand-down:before{content:"\\E130"}.glyphicon-circle-arrow-right:before{content:"\\E131"}.glyphicon-circle-arrow-left:before{content:"\\E132"}.glyphicon-circle-arrow-up:before{content:"\\E133"}.glyphicon-circle-arrow-down:before{content:"\\E134"}.glyphicon-globe:before{content:"\\E135"}.glyphicon-wrench:before{content:"\\E136"}.glyphicon-tasks:before{content:"\\E137"}.glyphicon-filter:before{content:"\\E138"}.glyphicon-briefcase:before{content:"\\E139"}.glyphicon-fullscreen:before{content:"\\E140"}.glyphicon-dashboard:before{content:"\\E141"}.glyphicon-paperclip:before{content:"\\E142"}.glyphicon-heart-empty:before{content:"\\E143"}.glyphicon-link:before{content:"\\E144"}.glyphicon-phone:before{content:"\\E145"}.glyphicon-pushpin:before{content:"\\E146"}.glyphicon-usd:before{content:"\\E148"}.glyphicon-gbp:before{content:"\\E149"}.glyphicon-sort:before{content:"\\E150"}.glyphicon-sort-by-alphabet:before{content:"\\E151"}.glyphicon-sort-by-alphabet-alt:before{content:"\\E152"}.glyphicon-sort-by-order:before{content:"\\E153"}.glyphicon-sort-by-order-alt:before{content:"\\E154"}.glyphicon-sort-by-attributes:before{content:"\\E155"}.glyphicon-sort-by-attributes-alt:before{content:"\\E156"}.glyphicon-unchecked:before{content:"\\E157"}.glyphicon-expand:before{content:"\\E158"}.glyphicon-collapse-down:before{content:"\\E159"}.glyphicon-collapse-up:before{content:"\\E160"}.glyphicon-log-in:before{content:"\\E161"}.glyphicon-flash:before{content:"\\E162"}.glyphicon-log-out:before{content:"\\E163"}.glyphicon-new-window:before{content:"\\E164"}.glyphicon-record:before{content:"\\E165"}.glyphicon-save:before{content:"\\E166"}.glyphicon-open:before{content:"\\E167"}.glyphicon-saved:before{content:"\\E168"}.glyphicon-import:before{content:"\\E169"}.glyphicon-export:before{content:"\\E170"}.glyphicon-send:before{content:"\\E171"}.glyphicon-floppy-disk:before{content:"\\E172"}.glyphicon-floppy-saved:before{content:"\\E173"}.glyphicon-floppy-remove:before{content:"\\E174"}.glyphicon-floppy-save:before{content:"\\E175"}.glyphicon-floppy-open:before{content:"\\E176"}.glyphicon-credit-card:before{content:"\\E177"}.glyphicon-transfer:before{content:"\\E178"}.glyphicon-cutlery:before{content:"\\E179"}.glyphicon-header:before{content:"\\E180"}.glyphicon-compressed:before{content:"\\E181"}.glyphicon-earphone:before{content:"\\E182"}.glyphicon-phone-alt:before{content:"\\E183"}.glyphicon-tower:before{content:"\\E184"}.glyphicon-stats:before{content:"\\E185"}.glyphicon-sd-video:before{content:"\\E186"}.glyphicon-hd-video:before{content:"\\E187"}.glyphicon-subtitles:before{content:"\\E188"}.glyphicon-sound-stereo:before{content:"\\E189"}.glyphicon-sound-dolby:before{content:"\\E190"}.glyphicon-sound-5-1:before{content:"\\E191"}.glyphicon-sound-6-1:before{content:"\\E192"}.glyphicon-sound-7-1:before{content:"\\E193"}.glyphicon-copyright-mark:before{content:"\\E194"}.glyphicon-registration-mark:before{content:"\\E195"}.glyphicon-cloud-download:before{content:"\\E197"}.glyphicon-cloud-upload:before{content:"\\E198"}.glyphicon-tree-conifer:before{content:"\\E199"}.glyphicon-tree-deciduous:before{content:"\\E200"}.glyphicon-cd:before{content:"\\E201"}.glyphicon-save-file:before{content:"\\E202"}.glyphicon-open-file:before{content:"\\E203"}.glyphicon-level-up:before{content:"\\E204"}.glyphicon-copy:before{content:"\\E205"}.glyphicon-paste:before{content:"\\E206"}.glyphicon-alert:before{content:"\\E209"}.glyphicon-equalizer:before{content:"\\E210"}.glyphicon-king:before{content:"\\E211"}.glyphicon-queen:before{content:"\\E212"}.glyphicon-pawn:before{content:"\\E213"}.glyphicon-bishop:before{content:"\\E214"}.glyphicon-knight:before{content:"\\E215"}.glyphicon-baby-formula:before{content:"\\E216"}.glyphicon-tent:before{content:"\\26FA"}.glyphicon-blackboard:before{content:"\\E218"}.glyphicon-bed:before{content:"\\E219"}.glyphicon-apple:before{content:"\\F8FF"}.glyphicon-erase:before{content:"\\E221"}.glyphicon-hourglass:before{content:"\\231B"}.glyphicon-lamp:before{content:"\\E223"}.glyphicon-duplicate:before{content:"\\E224"}.glyphicon-piggy-bank:before{content:"\\E225"}.glyphicon-scissors:before{content:"\\E226"}.glyphicon-bitcoin:before,.glyphicon-btc:before,.glyphicon-xbt:before{content:"\\E227"}.glyphicon-jpy:before,.glyphicon-yen:before{content:"\\A5"}.glyphicon-rub:before,.glyphicon-ruble:before{content:"\\20BD"}.glyphicon-scale:before{content:"\\E230"}.glyphicon-ice-lolly:before{content:"\\E231"}.glyphicon-ice-lolly-tasted:before{content:"\\E232"}.glyphicon-education:before{content:"\\E233"}.glyphicon-option-horizontal:before{content:"\\E234"}.glyphicon-option-vertical:before{content:"\\E235"}.glyphicon-menu-hamburger:before{content:"\\E236"}.glyphicon-modal-window:before{content:"\\E237"}.glyphicon-oil:before{content:"\\E238"}.glyphicon-grain:before{content:"\\E239"}.glyphicon-sunglasses:before{content:"\\E240"}.glyphicon-text-size:before{content:"\\E241"}.glyphicon-text-color:before{content:"\\E242"}.glyphicon-text-background:before{content:"\\E243"}.glyphicon-object-align-top:before{content:"\\E244"}.glyphicon-object-align-bottom:before{content:"\\E245"}.glyphicon-object-align-horizontal:before{content:"\\E246"}.glyphicon-object-align-left:before{content:"\\E247"}.glyphicon-object-align-vertical:before{content:"\\E248"}.glyphicon-object-align-right:before{content:"\\E249"}.glyphicon-triangle-right:before{content:"\\E250"}.glyphicon-triangle-left:before{content:"\\E251"}.glyphicon-triangle-bottom:before{content:"\\E252"}.glyphicon-triangle-top:before{content:"\\E253"}.glyphicon-console:before{content:"\\E254"}.glyphicon-superscript:before{content:"\\E255"}.glyphicon-subscript:before{content:"\\E256"}.glyphicon-menu-left:before{content:"\\E257"}.glyphicon-menu-right:before{content:"\\E258"}.glyphicon-menu-down:before{content:"\\E259"}.glyphicon-menu-up:before{content:"\\E260"}*,:after,:before{box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:9pt}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:1pc;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-inline,.list-unstyled{padding-left:0;list-style:none}.list-inline{margin-left:-5px}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:10pc;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:\'\\2014 \\A0\'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:\'\'}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:\'\\A0 \\2014\'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,Courier New,monospace}code{color:#c7254e;background-color:#f9f2f4;border-radius:4px}code,kbd{padding:2px 4px;font-size:90%}kbd{color:#fff;background-color:#333;border-radius:3px;box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777}caption,th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered,.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;margin:0}fieldset,legend{padding:0;border:0}legend{display:block;width:100%;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{padding-top:7px}.form-control,output{display:block;font-size:14px;line-height:1.42857143;color:#555}.form-control{width:100%;height:34px;padding:6px 9pt;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;box-shadow:inset 0 1px 1px rgba(0,0,0,.075);transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],.input-group-sm input[type=time],input[type=date].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm,input[type=time].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],.input-group-lg input[type=time],input[type=date].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg,input[type=time].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}.checkbox-inline.disabled,.checkbox.disabled label,.radio-inline.disabled,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio label,fieldset[disabled] .radio-inline,fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:9pt;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:9pt;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:2pc;padding:6px 10px;font-size:9pt;line-height:1.5}.input-lg{height:46px;padding:10px 1pc;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 1pc;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 1pc;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.333333px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:9pt}}.btn{display:inline-block;padding:6px 9pt;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.btn-default:hover,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary.active,.btn-primary:active,.btn-primary:hover,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success.active,.btn-success:active,.btn-success:hover,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info.active,.btn-info:active,.btn-info:hover,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.btn-warning:hover,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger.active,.btn-danger:active,.btn-danger:hover,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 1pc;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:9pt;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:9pt;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;transition-timing-function:ease;transition-duration:.35s;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10pc;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;box-shadow:0 6px 9pt rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:9pt;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:9pt;padding-left:9pt}.btn-group.open .dropdown-toggle{box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 1pc;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:9pt;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 9pt;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:9pt;border-radius:3px}.input-group-addon.input-lg{padding:10px 1pc;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{font-size:0;white-space:nowrap}.input-group-btn,.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li,.nav>li>a{position:relative;display:block}.nav>li>a{padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;box-shadow:inset 0 1px 0 hsla(0,0%,100%,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin:8px -15px;border-top:1px solid transparent;border-bottom:1px solid transparent;box-shadow:inset 0 1px 0 hsla(0,0%,100%,.1),0 1px 0 hsla(0,0%,100%,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-nav>li>a,.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>li>a,.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\\A0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 9pt;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:3;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 1pc;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:9pt;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:9pt;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;background-color:#eee}.jumbotron,.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:3pc;padding-bottom:3pc}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@keyframes progress-bar-stripes{0%{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:9pt;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:linear-gradient(45deg,hsla(0,0%,100%,.15) 25%,transparent 25%,transparent 50%,hsla(0,0%,100%,.15) 50%,hsla(0,0%,100%,.15) 75%,transparent 75%,transparent);background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:linear-gradient(45deg,hsla(0,0%,100%,.15) 25%,transparent 25%,transparent 50%,hsla(0,0%,100%,.15) 50%,hsla(0,0%,100%,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:linear-gradient(45deg,hsla(0,0%,100%,.15) 25%,transparent 25%,transparent 50%,hsla(0,0%,100%,.15) 50%,hsla(0,0%,100%,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:linear-gradient(45deg,hsla(0,0%,100%,.15) 25%,transparent 25%,transparent 50%,hsla(0,0%,100%,.15) 50%,hsla(0,0%,100%,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:linear-gradient(45deg,hsla(0,0%,100%,.15) 25%,transparent 25%,transparent 50%,hsla(0,0%,100%,.15) 50%,hsla(0,0%,100%,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:625pc}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle,.panel-title{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:1pc}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.list-group+.panel-footer,.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:transparent;border:0}.modal,.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0, -25%)}.modal.in .modal-dialog{transform:translate(0, 0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.42857143px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:9pt;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px}.tooltip.top-left .tooltip-arrow,.tooltip.top-right .tooltip-arrow{bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{left:5px}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel,.carousel-inner{position:relative}.carousel-inner{width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media (-webkit-transform-3d),all and (transform-3d){.carousel-inner>.item{transition:transform .6s ease-in-out;backface-visibility:hidden;perspective:750pt}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:linear-gradient(to right,rgba(0,0,0,.5) 0%,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=\'#80000000\',endColorstr=\'#00000000\',GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0%,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=\'#00000000\',endColorstr=\'#80000000\',GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:\'\\2039\'}.carousel-control .icon-next:before{content:\'\\203A\'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\\9;background-color:transparent;border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:9pt;height:9pt;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}',""]); },function(e,t){e.exports=function(){var e=[];return e.toString=function(){for(var e=[],t=0;t